mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Minor code revisions in preparation for cache system on 20.0+
This commit is contained in:
parent
291d2fd82f
commit
c094030c52
136
.clang-format
Normal file
136
.clang-format
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
---
|
||||
Language: Cpp
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveMacros: false
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: true
|
||||
AlignTrailingComments: true
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: true
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Never
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: None
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: true
|
||||
AfterClass: true
|
||||
AfterControlStatement: true
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: true
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: true
|
||||
BeforeCatch: true
|
||||
BeforeElse: true
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: true
|
||||
SplitEmptyRecord: true
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeInheritanceComma: false
|
||||
BreakInheritanceList: BeforeColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ExperimentalAutoDetectBinPacking: false
|
||||
FixNamespaceComments: true
|
||||
ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
SortPriority: 0
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
SortPriority: 0
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
SortPriority: 0
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
IncludeIsMainSourceRegex: ''
|
||||
IndentAccessModifiers: true
|
||||
IndentCaseLabels: true
|
||||
IndentGotoLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
JavaScriptQuotes: Leave
|
||||
JavaScriptWrapImports: true
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
ObjCBinPackProtocolList: Auto
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakAssignment: 2
|
||||
PenaltyBreakBeforeFirstCallParameter: 19
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyBreakTemplateDeclaration: 10
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 1000
|
||||
PointerAlignment: Right
|
||||
ReflowComments: false
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInConditionalStatement: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
SpaceBeforeSquareBrackets: false
|
||||
Standard: Latest
|
||||
StatementMacros:
|
||||
- Q_UNUSED
|
||||
- QT_REQUIRE_VERSION
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
...
|
||||
9
.clang-tidy
Normal file
9
.clang-tidy
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
Checks: 'clang-analyzer-*,cppcoreguidelines-*,modernize-*,bugprone-*,performance-*,readability-*,readability-non-const-parameter,misc-const-correctness,misc-use-anonymous-namespace,google-explicit-constructor,-modernize-use-trailing-return-type,-bugprone-exception-escape,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-avoid-magic-numbers,-bugprone-easily-swappable-parameters,-cppcoreguidelines-non-private-member-variables-in-classes'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
CheckOptions:
|
||||
- key: readability-magic-numbers.IgnoredFloatingPointValues
|
||||
value: '0.0;1.0;100.0;'
|
||||
- key: readability-magic-numbers.IgnoredIntegerValues
|
||||
value: '0;1;2;3;4;5;6;7;8;9;'
|
||||
11
.gitattributes
vendored
Normal file
11
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# Set the default behavior for all files.
|
||||
* text=auto eol=lf
|
||||
|
||||
# Normalized and converts to native line endings on checkout.
|
||||
*.c text
|
||||
*.cc text
|
||||
*.cxx
|
||||
*.cpp text
|
||||
*.h text
|
||||
*.hxx text
|
||||
*.hpp text
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -2,6 +2,7 @@ build/
|
|||
.vscode/
|
||||
*.cbp
|
||||
*.layout
|
||||
.editorconfig
|
||||
|
||||
.idea/
|
||||
cmake-build-debug/
|
||||
|
|
|
|||
21
inc/cfg.h
21
inc/cfg.h
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace cfg
|
||||
{
|
||||
|
|
@ -17,18 +18,18 @@ namespace cfg
|
|||
void loadConfig();
|
||||
void saveConfig();
|
||||
|
||||
bool isBlacklisted(const uint64_t& tid);
|
||||
bool isBlacklisted(uint64_t tid);
|
||||
void addTitleToBlacklist(void *a);
|
||||
void removeTitleFromBlacklist(const uint64_t& tid);
|
||||
void removeTitleFromBlacklist(uint64_t tid);
|
||||
|
||||
bool isFavorite(const uint64_t& tid);
|
||||
void addTitleToFavorites(const uint64_t& tid);
|
||||
bool isFavorite(uint64_t tid);
|
||||
void addTitleToFavorites(uint64_t tid);
|
||||
|
||||
bool isDefined(const uint64_t& tid);
|
||||
void pathDefAdd(const uint64_t& tid, const std::string& newPath);
|
||||
std::string getPathDefinition(const uint64_t& tid);
|
||||
bool isDefined(uint64_t tid);
|
||||
void pathDefAdd(uint64_t tid, const std::string &newPath);
|
||||
std::string getPathDefinition(uint64_t tid);
|
||||
|
||||
void addPathToFilter(const uint64_t& tid, const std::string& _p);
|
||||
void addPathToFilter(uint64_t tid, const std::string &_p);
|
||||
|
||||
extern std::unordered_map<std::string, bool> config;
|
||||
extern std::vector<uint64_t> blacklist;
|
||||
|
|
@ -36,4 +37,4 @@ namespace cfg
|
|||
extern uint8_t sortType;
|
||||
extern std::string driveClientID, driveClientSecret, driveRefreshToken;
|
||||
extern std::string webdavOrigin, webdavBasePath, webdavUser, webdavPassword;
|
||||
}
|
||||
} // namespace cfg
|
||||
|
|
|
|||
118
inc/data.h
118
inc/data.h
|
|
@ -1,87 +1,115 @@
|
|||
#pragma once
|
||||
#include <switch.h>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "gfx.h"
|
||||
|
||||
#define BLD_MON 11
|
||||
#define BLD_DAY 5
|
||||
#define BLD_YEAR 2024
|
||||
#define BLD_MON 5
|
||||
#define BLD_DAY 28
|
||||
#define BLD_YEAR 2025
|
||||
|
||||
namespace data
|
||||
{
|
||||
//Loads user + title info
|
||||
// Loads user + title info
|
||||
void init();
|
||||
void exit();
|
||||
bool loadUsersTitles(bool clearUsers);
|
||||
void sortUserTitles();
|
||||
|
||||
//Draws some stats to the upper left corner
|
||||
// Draws some stats to the upper left corner
|
||||
void dispStats();
|
||||
|
||||
//Global stuff for all titles/saves
|
||||
// Global stuff for all titles/saves
|
||||
typedef struct
|
||||
{
|
||||
NacpStruct nacp;
|
||||
std::string title, safeTitle, author;//Shortcuts sorta.
|
||||
SDL_Texture *icon = NULL;
|
||||
bool fav;
|
||||
/// @brief Control data.
|
||||
NsApplicationControlData data;
|
||||
|
||||
/// @brief Saves whether or not the title has valid control data.
|
||||
bool hasControlData = false;
|
||||
|
||||
std::string title, safeTitle, author;
|
||||
SDL_Texture *icon = NULL;
|
||||
bool fav;
|
||||
} titleInfo;
|
||||
|
||||
//Holds stuff specific to user's titles/saves
|
||||
// Holds stuff specific to user's titles/saves
|
||||
typedef struct
|
||||
{
|
||||
//Makes it easier to grab id
|
||||
uint64_t tid;
|
||||
FsSaveDataInfo saveInfo;
|
||||
PdmPlayStatistics playStats;
|
||||
// Makes it easier to grab id
|
||||
uint64_t tid;
|
||||
FsSaveDataInfo saveInfo;
|
||||
PdmPlayStatistics playStats;
|
||||
} userTitleInfo;
|
||||
|
||||
//Class to store user info + titles
|
||||
// Class to store user info + titles
|
||||
class user
|
||||
{
|
||||
public:
|
||||
user() = default;
|
||||
user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName);
|
||||
user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName, SDL_Texture *img);
|
||||
user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName);
|
||||
user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName, SDL_Texture *img);
|
||||
|
||||
//Sets ID
|
||||
void setUID(const AccountUid& _id);
|
||||
// Sets ID
|
||||
void setUID(AccountUid _id);
|
||||
|
||||
//Assigns icon
|
||||
void assignIcon(SDL_Texture *_icn) { userIcon = _icn; }
|
||||
// Assigns icon
|
||||
void assignIcon(SDL_Texture *_icn)
|
||||
{
|
||||
userIcon = _icn;
|
||||
}
|
||||
|
||||
//Returns user ID
|
||||
AccountUid getUID() const { return userID; }
|
||||
u128 getUID128() const { return uID128; }
|
||||
// Returns user ID
|
||||
AccountUid getUID() const
|
||||
{
|
||||
return userID;
|
||||
}
|
||||
u128 getUID128() const
|
||||
{
|
||||
return uID128;
|
||||
}
|
||||
|
||||
//Returns username
|
||||
std::string getUsername() const { return username; }
|
||||
std::string getUsernameSafe() const { return userSafe; }
|
||||
// Returns username
|
||||
std::string getUsername() const
|
||||
{
|
||||
return username;
|
||||
}
|
||||
std::string getUsernameSafe() const
|
||||
{
|
||||
return userSafe;
|
||||
}
|
||||
|
||||
SDL_Texture *getUserIcon(){ return userIcon; }
|
||||
void delIcon(){ SDL_DestroyTexture(userIcon); }
|
||||
SDL_Texture *getUserIcon()
|
||||
{
|
||||
return userIcon;
|
||||
}
|
||||
void delIcon()
|
||||
{
|
||||
SDL_DestroyTexture(userIcon);
|
||||
}
|
||||
|
||||
std::vector<data::userTitleInfo> titleInfo;
|
||||
void addUserTitleInfo(const uint64_t& _tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats);
|
||||
void addUserTitleInfo(const uint64_t &_tid,
|
||||
const FsSaveDataInfo *_saveInfo,
|
||||
const PdmPlayStatistics *_stats);
|
||||
|
||||
private:
|
||||
AccountUid userID;
|
||||
u128 uID128;
|
||||
std::string username, userSafe;
|
||||
//User icon
|
||||
// User icon
|
||||
SDL_Texture *userIcon;
|
||||
};
|
||||
|
||||
//User vector
|
||||
// User vector
|
||||
extern std::vector<user> users;
|
||||
//Title data/info map
|
||||
// Title data/info map
|
||||
extern std::unordered_map<uint64_t, data::titleInfo> titles;
|
||||
|
||||
//Sets/Retrieves current user/title
|
||||
// Sets/Retrieves current user/title
|
||||
void setUserIndex(unsigned _sUser);
|
||||
data::user *getCurrentUser();
|
||||
unsigned getCurrentUserIndex();
|
||||
|
|
@ -90,14 +118,14 @@ namespace data
|
|||
data::userTitleInfo *getCurrentUserTitleInfo();
|
||||
unsigned getCurrentUserTitleInfoIndex();
|
||||
|
||||
//Gets pointer to info that also has title + nacp
|
||||
data::titleInfo *getTitleInfoByTID(const uint64_t& tid);
|
||||
// Gets pointer to info that also has title + nacp
|
||||
data::titleInfo *getTitleInfoByTID(const uint64_t &tid);
|
||||
|
||||
//More shortcut functions
|
||||
std::string getTitleNameByTID(const uint64_t& tid);
|
||||
std::string getTitleSafeNameByTID(const uint64_t& tid);
|
||||
SDL_Texture *getTitleIconByTID(const uint64_t& tid);
|
||||
int getTitleIndexInUser(const data::user& u, const uint64_t& tid);
|
||||
// More shortcut functions
|
||||
std::string getTitleNameByTID(const uint64_t &tid);
|
||||
std::string getTitleSafeNameByTID(const uint64_t &tid);
|
||||
SDL_Texture *getTitleIconByTID(const uint64_t &tid);
|
||||
int getTitleIndexInUser(const data::user &u, const uint64_t &tid);
|
||||
extern SetLanguage sysLang;
|
||||
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
|
|
|
|||
34
inc/fs.h
34
inc/fs.h
|
|
@ -1,14 +1,14 @@
|
|||
#pragma once
|
||||
|
||||
#include <minizip/zip.h>
|
||||
#include <minizip/unzip.h>
|
||||
#include <minizip/zip.h>
|
||||
|
||||
#include "fs/fstype.h"
|
||||
#include "fs/file.h"
|
||||
#include "fs/dir.h"
|
||||
#include "fs/zip.h"
|
||||
#include "fs/file.h"
|
||||
#include "fs/fsfile.h"
|
||||
#include "fs/fstype.h"
|
||||
#include "fs/remote.h"
|
||||
#include "fs/zip.h"
|
||||
#include "ui/miscui.h"
|
||||
|
||||
#define BUFF_SIZE 0x4000
|
||||
|
|
@ -17,19 +17,29 @@
|
|||
|
||||
namespace fs
|
||||
{
|
||||
copyArgs *copyArgsCreate(const std::string& src, const std::string& dst, const std::string& dev, zipFile z, unzFile unz, bool _cleanup, bool _trimZipPath, uint8_t _trimPlaces);
|
||||
copyArgs *copyArgsCreate(const std::string &src,
|
||||
const std::string &dst,
|
||||
const std::string &dev,
|
||||
zipFile z,
|
||||
unzFile unz,
|
||||
bool _cleanup,
|
||||
bool _trimZipPath,
|
||||
uint8_t _trimPlaces);
|
||||
void copyArgsDestroy(copyArgs *c);
|
||||
|
||||
void init();
|
||||
bool mountSave(const FsSaveDataInfo& _m);
|
||||
inline bool unmountSave() { return fsdevUnmountDevice("sv") == 0; }
|
||||
bool commitToDevice(const std::string& dev);
|
||||
bool mountSave(const FsSaveDataInfo &_m);
|
||||
inline bool unmountSave()
|
||||
{
|
||||
return fsdevUnmountDevice("sv") == 0;
|
||||
}
|
||||
bool commitToDevice(const std::string &dev);
|
||||
std::string getWorkDir();
|
||||
void setWorkDir(const std::string& _w);
|
||||
void setWorkDir(const std::string &_w);
|
||||
|
||||
//Loads paths to filter from backup/deletion
|
||||
void loadPathFilters(const uint64_t& tid);
|
||||
bool pathIsFiltered(const std::string& _path);
|
||||
void loadPathFilters(uint64_t tid);
|
||||
bool pathIsFiltered(const std::string &_path);
|
||||
void freePathFilters();
|
||||
|
||||
void createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _uid, threadInfo *t);
|
||||
|
|
@ -52,4 +62,4 @@ namespace fs
|
|||
|
||||
void logOpen();
|
||||
void logWrite(const char *fmt, ...);
|
||||
}
|
||||
} // namespace fs
|
||||
|
|
|
|||
73
inc/fs/dir.h
73
inc/fs/dir.h
|
|
@ -1,31 +1,41 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "type.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fs
|
||||
{
|
||||
void mkDir(const std::string& _p);
|
||||
void mkDirRec(const std::string& _p);
|
||||
void delDir(const std::string& _p);
|
||||
bool dirNotEmpty(const std::string& _dir);
|
||||
bool isDir(const std::string& _path);
|
||||
void mkDir(const std::string &_p);
|
||||
void mkDirRec(const std::string &_p);
|
||||
void delDir(const std::string &_p);
|
||||
bool dirNotEmpty(const std::string &_dir);
|
||||
bool isDir(const std::string &_path);
|
||||
|
||||
//threadInfo is optional. Only for updating task status.
|
||||
void copyDirToDir(const std::string& src, const std::string& dst, threadInfo *t);
|
||||
void copyDirToDirThreaded(const std::string& src, const std::string& dst);
|
||||
void copyDirToDirCommit(const std::string& src, const std::string& dst, const std::string& dev, threadInfo *t);
|
||||
void copyDirToDirCommitThreaded(const std::string& src, const std::string& dst, const std::string& dev);
|
||||
void getDirProps(const std::string& path, unsigned& dirCount, unsigned& fileCount, uint64_t& totalSize);
|
||||
void copyDirToDir(const std::string &src, const std::string &dst, threadInfo *t);
|
||||
void copyDirToDirThreaded(const std::string &src, const std::string &dst);
|
||||
void copyDirToDirCommit(const std::string &src, const std::string &dst, const std::string &dev, threadInfo *t);
|
||||
void copyDirToDirCommitThreaded(const std::string &src, const std::string &dst, const std::string &dev);
|
||||
void getDirProps(const std::string &path, unsigned &dirCount, unsigned &fileCount, uint64_t &totalSize);
|
||||
|
||||
class dirItem
|
||||
{
|
||||
public:
|
||||
dirItem(const std::string& pathTo, const std::string& sItem);
|
||||
std::string getItm() const { return itm; }
|
||||
dirItem(const std::string &pathTo, const std::string &sItem);
|
||||
std::string getItm() const
|
||||
{
|
||||
return itm;
|
||||
}
|
||||
|
||||
std::string getName() const;
|
||||
|
||||
std::string getExt() const;
|
||||
bool isDir() const { return dir; }
|
||||
|
||||
bool isDir() const
|
||||
{
|
||||
return dir;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string itm;
|
||||
|
|
@ -37,18 +47,37 @@ namespace fs
|
|||
{
|
||||
public:
|
||||
dirList() = default;
|
||||
dirList(const std::string& _path, bool ignoreDotFiles = false);
|
||||
void reassign(const std::string& _path);
|
||||
dirList(const std::string &_path, bool ignoreDotFiles = false);
|
||||
void reassign(const std::string &_path);
|
||||
void rescan();
|
||||
|
||||
std::string getItem(int index) const { return item[index].getItm(); }
|
||||
std::string getItemExt(int index) const { return item[index].getExt(); }
|
||||
bool isDir(int index) const { return item[index].isDir(); }
|
||||
unsigned getCount() const { return item.size(); }
|
||||
fs::dirItem *getDirItemAt(unsigned int _ind) { return &item[_ind]; }
|
||||
std::string getItem(int index) const
|
||||
{
|
||||
return item[index].getItm();
|
||||
}
|
||||
|
||||
std::string getItemExt(int index) const
|
||||
{
|
||||
return item[index].getExt();
|
||||
}
|
||||
|
||||
bool isDir(int index) const
|
||||
{
|
||||
return item[index].isDir();
|
||||
}
|
||||
|
||||
unsigned getCount() const
|
||||
{
|
||||
return item.size();
|
||||
}
|
||||
|
||||
fs::dirItem *getDirItemAt(unsigned int _ind)
|
||||
{
|
||||
return &item[_ind];
|
||||
}
|
||||
|
||||
private:
|
||||
std::string path;
|
||||
std::vector<dirItem> item;
|
||||
};
|
||||
}
|
||||
} // namespace fs
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace ui
|
|||
{
|
||||
void fmInit();
|
||||
void fmExit();
|
||||
void fmPrep(const FsSaveDataType& _type, const std::string& _dev, const std::string& _baseSDMC, bool _commit);
|
||||
void fmPrep(FsSaveDataType _type, const std::string &_dev, const std::string &_baseSDMC, bool _commit);
|
||||
void fmUpdate();
|
||||
void fmDraw(SDL_Texture *target);
|
||||
}
|
||||
} // namespace ui
|
||||
|
|
|
|||
105
inc/ui/miscui.h
105
inc/ui/miscui.h
|
|
@ -1,10 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <vector>
|
||||
|
||||
#include "type.h"
|
||||
#include "gfx.h"
|
||||
#include "type.h"
|
||||
|
||||
#define POP_FRAME_DEFAULT 130
|
||||
|
||||
|
|
@ -26,50 +26,60 @@ namespace ui
|
|||
{
|
||||
typedef struct
|
||||
{
|
||||
std::string text;
|
||||
bool hold;
|
||||
funcPtr confFunc, cancelFunc;
|
||||
void *args;
|
||||
unsigned lgFrame = 0, frameCount = 0;//To count frames cause I don't have time and am lazy
|
||||
std::string text;
|
||||
bool hold;
|
||||
funcPtr confFunc, cancelFunc;
|
||||
void *args;
|
||||
unsigned lgFrame = 0, frameCount = 0; //To count frames cause I don't have time and am lazy
|
||||
} confirmArgs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
funcPtr func = NULL;
|
||||
void *args = NULL;
|
||||
HidNpadButton button = (HidNpadButton)0;
|
||||
funcPtr func = NULL;
|
||||
void *args = NULL;
|
||||
HidNpadButton button = (HidNpadButton)0;
|
||||
} menuOptEvent;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_Texture *icn = NULL;
|
||||
std::string txt;
|
||||
int txtWidth;
|
||||
std::vector<menuOptEvent> events;
|
||||
SDL_Texture *icn = NULL;
|
||||
std::string txt;
|
||||
int txtWidth;
|
||||
std::vector<menuOptEvent> events;
|
||||
} menuOpt;
|
||||
|
||||
class menu
|
||||
{
|
||||
public:
|
||||
menu() = default;
|
||||
menu(const int& _x, const int& _y, const int& _rW, const int& _fS, const int& _mL);
|
||||
menu(int _x, int _y, int _rW, int _fS, int _mL);
|
||||
void editParam(int _param, int newVal);
|
||||
|
||||
//Gets executed when menu changes at all
|
||||
void setOnChangeFunc(funcPtr func) { onChange = func; }
|
||||
void setOnChangeFunc(funcPtr func)
|
||||
{
|
||||
onChange = func;
|
||||
}
|
||||
|
||||
//executed when .update() is called.
|
||||
void setCallback(funcPtr _callback, void *args) { callback = _callback; callbackArgs = args; }
|
||||
void setCallback(funcPtr _callback, void *args)
|
||||
{
|
||||
callback = _callback;
|
||||
callbackArgs = args;
|
||||
}
|
||||
|
||||
//Adds option.
|
||||
int addOpt(SDL_Texture *_icn, const std::string& add);
|
||||
int addOpt(SDL_Texture *_icn, const std::string &add);
|
||||
|
||||
//Adds an function to be executed on pressing button specified
|
||||
void optAddButtonEvent(unsigned _ind, HidNpadButton _button, funcPtr _func, void *args);
|
||||
//Changes opt text
|
||||
void editOpt(int ind, SDL_Texture *_icn, const std::string& ch);
|
||||
size_t getOptCount() { return opt.size(); }
|
||||
int getOptPos(const std::string& txt);
|
||||
void editOpt(int ind, SDL_Texture *_icn, const std::string &ch);
|
||||
size_t getOptCount()
|
||||
{
|
||||
return opt.size();
|
||||
}
|
||||
int getOptPos(const std::string &txt);
|
||||
|
||||
//Clears menu stuff
|
||||
~menu();
|
||||
|
|
@ -78,10 +88,16 @@ namespace ui
|
|||
void update();
|
||||
|
||||
//Returns selected option
|
||||
int getSelected() { return selected; }
|
||||
int getSelected()
|
||||
{
|
||||
return selected;
|
||||
}
|
||||
|
||||
//Returns menu option count
|
||||
int getCount() { return opt.size(); }
|
||||
int getCount()
|
||||
{
|
||||
return opt.size();
|
||||
}
|
||||
|
||||
//Draws the menu at x and y. rectWidth is the width of the rectangle drawn under the selected
|
||||
void draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText);
|
||||
|
|
@ -90,11 +106,17 @@ namespace ui
|
|||
void reset();
|
||||
|
||||
//Resets selected + start
|
||||
void resetSel() { selected = 0; }
|
||||
void resetSel()
|
||||
{
|
||||
selected = 0;
|
||||
}
|
||||
|
||||
//Enables control/disables drawing select box
|
||||
void setActive(bool _set);
|
||||
bool getActive() { return isActive; }
|
||||
bool getActive()
|
||||
{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
private:
|
||||
//drawing x and y + rectangle width/height. Height is calc'd with font size
|
||||
|
|
@ -118,15 +140,18 @@ namespace ui
|
|||
public:
|
||||
//Constructor. _max is the maximum value
|
||||
progBar() = default;
|
||||
progBar(const uint64_t& _max) { max = _max; }
|
||||
progBar(uint64_t _max) : max(_max) {};
|
||||
|
||||
void setMax(const uint64_t& _max) { max = _max; };
|
||||
void setMax(uint64_t _max)
|
||||
{
|
||||
max = _max;
|
||||
}
|
||||
|
||||
//Updates progress
|
||||
void update(const uint64_t& _prog);
|
||||
void update(uint64_t _prog);
|
||||
|
||||
//Draws with text at top
|
||||
void draw(const std::string& text);
|
||||
void draw(const std::string &text);
|
||||
|
||||
private:
|
||||
uint64_t max = 0, prog = 0;
|
||||
|
|
@ -135,8 +160,8 @@ namespace ui
|
|||
|
||||
typedef struct
|
||||
{
|
||||
std::string message;
|
||||
int rectWidth = 0, frames = 0, y = 720;
|
||||
std::string message;
|
||||
int rectWidth = 0, frames = 0, y = 720;
|
||||
} popMessage;
|
||||
|
||||
class popMessageMngr
|
||||
|
|
@ -146,20 +171,26 @@ namespace ui
|
|||
|
||||
void update();
|
||||
|
||||
void popMessageAdd(const std::string& mess, int frameTime);
|
||||
void popMessageAdd(const std::string &mess, int frameTime);
|
||||
void draw();
|
||||
|
||||
private:
|
||||
std::vector<popMessage> popQueue;//All graphics need to be on main thread. Directly adding will cause text issues
|
||||
std::vector<popMessage>
|
||||
popQueue; //All graphics need to be on main thread. Directly adding will cause text issues
|
||||
std::vector<popMessage> message;
|
||||
};
|
||||
|
||||
//General use
|
||||
ui::confirmArgs *confirmArgsCreate(bool _hold, funcPtr _confFunc, funcPtr _cancelFunc, void *_funcArgs, const char *fmt, ...);
|
||||
ui::confirmArgs *confirmArgsCreate(bool _hold,
|
||||
funcPtr _confFunc,
|
||||
funcPtr _cancelFunc,
|
||||
void *_funcArgs,
|
||||
const char *fmt,
|
||||
...);
|
||||
void confirm(void *a);
|
||||
void showMessage(const char *fmt, ...);
|
||||
bool confirmTransfer(const std::string& f, const std::string& t);
|
||||
bool confirmDelete(const std::string& p);
|
||||
bool confirmTransfer(const std::string &f, const std::string &t);
|
||||
bool confirmDelete(const std::string &p);
|
||||
void drawBoundBox(SDL_Texture *target, int x, int y, int w, int h, uint8_t clrSh);
|
||||
void drawTextbox(SDL_Texture *target, int x, int y, int w, int h);
|
||||
}
|
||||
} // namespace ui
|
||||
|
|
|
|||
47
inc/util.h
47
inc/util.h
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "data.h"
|
||||
#include "ui.h"
|
||||
#include "file.h"
|
||||
#include "gfx.h"
|
||||
#include "ui.h"
|
||||
|
||||
namespace util
|
||||
{
|
||||
|
|
@ -71,34 +71,39 @@ namespace util
|
|||
std::string getDateTime(int fmt);
|
||||
|
||||
//Copys dir list to a menu with 'D: ' + 'F: '
|
||||
void copyDirListToMenu(const 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);
|
||||
size_t getTotalPlacesInPath(const std::string& _path);
|
||||
void trimPath(std::string& _path, uint8_t _places);
|
||||
void removeLastFolderFromString(std::string &_path);
|
||||
size_t getTotalPlacesInPath(const std::string &_path);
|
||||
void trimPath(std::string &_path, uint8_t _places);
|
||||
|
||||
inline bool isASCII(const uint32_t& t)
|
||||
inline bool isASCII(uint32_t t)
|
||||
{
|
||||
return t > 30 && t < 127;
|
||||
}
|
||||
|
||||
std::string safeString(const std::string& s);
|
||||
std::string safeString(const std::string &s);
|
||||
|
||||
std::string getStringInput(SwkbdType _type, const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[]);
|
||||
std::string getStringInput(SwkbdType _type,
|
||||
const std::string &def,
|
||||
const std::string &head,
|
||||
size_t maxLength,
|
||||
unsigned dictCnt,
|
||||
const std::string dictWords[]);
|
||||
|
||||
std::string getExtensionFromString(const std::string& get);
|
||||
std::string getFilenameFromPath(const std::string& get);
|
||||
std::string getExtensionFromString(const std::string &get);
|
||||
std::string getFilenameFromPath(const std::string &get);
|
||||
|
||||
std::string generateAbbrev(const uint64_t& tid);
|
||||
std::string generateAbbrev(uint64_t tid);
|
||||
|
||||
//removes char from C++ string
|
||||
void stripChar(char _c, std::string& _s);
|
||||
void stripChar(char _c, std::string &_s);
|
||||
|
||||
void replaceStr(std::string& _str, const std::string& _find, const std::string& _rep);
|
||||
void replaceStr(std::string &_str, const std::string &_find, const std::string &_rep);
|
||||
|
||||
//For future external translation support. Replaces [button] with button chars
|
||||
void replaceButtonsInString(std::string& rep);
|
||||
void replaceButtonsInString(std::string &rep);
|
||||
|
||||
//Creates a basic generic icon for stuff without one
|
||||
SDL_Texture *createIconGeneric(const char *txt, int fontSize, bool clearBack);
|
||||
|
|
@ -116,35 +121,33 @@ namespace util
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline std::string getIDStr(const uint64_t& _id)
|
||||
inline std::string getIDStr(uint64_t _id)
|
||||
{
|
||||
char tmp[18];
|
||||
sprintf(tmp, "%016lX", _id);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
inline std::string getIDStrLower(const uint64_t& _id)
|
||||
inline std::string getIDStrLower(uint64_t _id)
|
||||
{
|
||||
char tmp[18];
|
||||
sprintf(tmp, "%08X", (uint32_t)_id);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
inline std::string generatePathByTID(const uint64_t& tid)
|
||||
inline std::string generatePathByTID(uint64_t tid)
|
||||
{
|
||||
return fs::getWorkDir() + data::getTitleSafeNameByTID(tid) + "/";
|
||||
}
|
||||
|
||||
std::string getSizeString(const uint64_t& _size);
|
||||
std::string getSizeString(uint64_t _size);
|
||||
|
||||
inline void createTitleDirectoryByTID(const uint64_t& tid)
|
||||
inline void createTitleDirectoryByTID(uint64_t tid)
|
||||
{
|
||||
std::string makePath = fs::getWorkDir() + data::getTitleSafeNameByTID(tid);
|
||||
mkdir(makePath.c_str(), 777);
|
||||
}
|
||||
|
||||
Result accountDeleteUser(AccountUid *uid);
|
||||
|
||||
void sysBoost();
|
||||
void sysNormal();
|
||||
|
||||
|
|
@ -155,4 +158,4 @@ namespace util
|
|||
}
|
||||
|
||||
void checkForUpdate(void *a);
|
||||
}
|
||||
} // namespace util
|
||||
|
|
|
|||
219
src/cfg.cpp
219
src/cfg.cpp
|
|
@ -1,14 +1,14 @@
|
|||
#include <switch.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <json-c/json.h>
|
||||
#include <string>
|
||||
#include <switch.h>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "cfg.h"
|
||||
#include "data.h"
|
||||
#include "file.h"
|
||||
#include "type.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "type.h"
|
||||
|
||||
std::unordered_map<std::string, bool> cfg::config;
|
||||
std::vector<uint64_t> cfg::blacklist;
|
||||
|
|
@ -19,21 +19,38 @@ std::string cfg::driveClientID, cfg::driveClientSecret, cfg::driveRefreshToken;
|
|||
std::string cfg::webdavOrigin, cfg::webdavBasePath, cfg::webdavUser, cfg::webdavPassword;
|
||||
|
||||
|
||||
const char *cfgPath = "sdmc:/config/JKSV/JKSV.cfg", *titleDefPath = "sdmc:/config/JKSV/titleDefs.txt", *workDirLegacy = "sdmc:/switch/jksv_dir.txt";
|
||||
static std::unordered_map<std::string, unsigned> cfgStrings =
|
||||
{
|
||||
{"workDir", 0}, {"includeDeviceSaves", 1}, {"autoBackup", 2}, {"overclock", 3}, {"holdToDelete", 4}, {"holdToRestore", 5},
|
||||
{"holdToOverwrite", 6}, {"forceMount", 7}, {"accountSystemSaves", 8}, {"allowSystemSaveWrite", 9}, {"directFSCommands", 10},
|
||||
{"exportToZIP", 11}, {"languageOverride", 12}, {"enableTrashBin", 13}, {"titleSortType", 14}, {"animationScale", 15},
|
||||
{"favorite", 16}, {"blacklist", 17}, {"autoName", 18}, {"driveRefreshToken", 19},
|
||||
const char *cfgPath = "sdmc:/config/JKSV/JKSV.cfg", *titleDefPath = "sdmc:/config/JKSV/titleDefs.txt",
|
||||
*workDirLegacy = "sdmc:/switch/jksv_dir.txt";
|
||||
static std::unordered_map<std::string, unsigned> cfgStrings = {
|
||||
{"workDir", 0},
|
||||
{"includeDeviceSaves", 1},
|
||||
{"autoBackup", 2},
|
||||
{"overclock", 3},
|
||||
{"holdToDelete", 4},
|
||||
{"holdToRestore", 5},
|
||||
{"holdToOverwrite", 6},
|
||||
{"forceMount", 7},
|
||||
{"accountSystemSaves", 8},
|
||||
{"allowSystemSaveWrite", 9},
|
||||
{"directFSCommands", 10},
|
||||
{"exportToZIP", 11},
|
||||
{"languageOverride", 12},
|
||||
{"enableTrashBin", 13},
|
||||
{"titleSortType", 14},
|
||||
{"animationScale", 15},
|
||||
{"favorite", 16},
|
||||
{"blacklist", 17},
|
||||
{"autoName", 18},
|
||||
{"driveRefreshToken", 19},
|
||||
};
|
||||
|
||||
const std::string _true_ = "true", _false_ = "false";
|
||||
|
||||
bool cfg::isBlacklisted(const uint64_t& tid)
|
||||
bool cfg::isBlacklisted(uint64_t tid)
|
||||
{
|
||||
for(uint64_t& bid : cfg::blacklist)
|
||||
if(tid == bid) return true;
|
||||
for (uint64_t &bid : cfg::blacklist)
|
||||
if (tid == bid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -45,21 +62,22 @@ void cfg::addTitleToBlacklist(void *a)
|
|||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
uint64_t tid = d->tid;
|
||||
cfg::blacklist.push_back(tid);
|
||||
for(data::user& u : data::users)
|
||||
for (data::user &u : data::users)
|
||||
{
|
||||
for(unsigned i = 0; i < u.titleInfo.size(); i++)
|
||||
if(u.titleInfo[i].tid == tid) u.titleInfo.erase(u.titleInfo.begin() + i);
|
||||
for (unsigned i = 0; i < u.titleInfo.size(); i++)
|
||||
if (u.titleInfo[i].tid == tid)
|
||||
u.titleInfo.erase(u.titleInfo.begin() + i);
|
||||
}
|
||||
ui::ttlRefresh();
|
||||
cfg::saveConfig();
|
||||
t->finished = true;
|
||||
}
|
||||
|
||||
void cfg::removeTitleFromBlacklist(const uint64_t& tid)
|
||||
void cfg::removeTitleFromBlacklist(uint64_t tid)
|
||||
{
|
||||
for(unsigned i = 0; i < cfg::blacklist.size(); i++)
|
||||
for (unsigned i = 0; i < cfg::blacklist.size(); i++)
|
||||
{
|
||||
if(cfg::blacklist[i] == tid)
|
||||
if (cfg::blacklist[i] == tid)
|
||||
cfg::blacklist.erase(cfg::blacklist.begin() + i);
|
||||
}
|
||||
data::loadUsersTitles(false);
|
||||
|
|
@ -67,27 +85,28 @@ void cfg::removeTitleFromBlacklist(const uint64_t& tid)
|
|||
cfg::saveConfig();
|
||||
}
|
||||
|
||||
bool cfg::isFavorite(const uint64_t& tid)
|
||||
bool cfg::isFavorite(uint64_t tid)
|
||||
{
|
||||
for(uint64_t& fid : cfg::favorites)
|
||||
if(tid == fid) return true;
|
||||
for (uint64_t &fid : cfg::favorites)
|
||||
if (tid == fid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int getFavoriteIndex(const uint64_t& tid)
|
||||
static int getFavoriteIndex(uint64_t tid)
|
||||
{
|
||||
for(unsigned i = 0; i < cfg::favorites.size(); i++)
|
||||
for (unsigned i = 0; i < cfg::favorites.size(); i++)
|
||||
{
|
||||
if(tid == cfg::favorites[i])
|
||||
if (tid == cfg::favorites[i])
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void cfg::addTitleToFavorites(const uint64_t& tid)
|
||||
void cfg::addTitleToFavorites(uint64_t tid)
|
||||
{
|
||||
if(cfg::isFavorite(tid))
|
||||
if (cfg::isFavorite(tid))
|
||||
{
|
||||
int rem = getFavoriteIndex(tid);
|
||||
cfg::favorites.erase(cfg::favorites.begin() + rem);
|
||||
|
|
@ -100,20 +119,21 @@ void cfg::addTitleToFavorites(const uint64_t& tid)
|
|||
cfg::saveConfig();
|
||||
}
|
||||
|
||||
bool cfg::isDefined(const uint64_t& tid)
|
||||
bool cfg::isDefined(uint64_t tid)
|
||||
{
|
||||
for(auto& def : pathDefs)
|
||||
if(def.first == tid) return true;
|
||||
for (auto &def : pathDefs)
|
||||
if (def.first == tid)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void cfg::pathDefAdd(const uint64_t& tid, const std::string& newPath)
|
||||
void cfg::pathDefAdd(uint64_t tid, const std::string &newPath)
|
||||
{
|
||||
data::titleInfo *t = data::getTitleInfoByTID(tid);
|
||||
std::string oldSafe = t->safeTitle;
|
||||
std::string tmp = util::safeString(newPath);
|
||||
if(!tmp.empty())
|
||||
if (!tmp.empty())
|
||||
{
|
||||
pathDefs[tid] = tmp;
|
||||
t->safeTitle = tmp;
|
||||
|
|
@ -122,18 +142,21 @@ void cfg::pathDefAdd(const uint64_t& tid, const std::string& newPath)
|
|||
std::string newOutput = fs::getWorkDir() + tmp;
|
||||
rename(oldOutput.c_str(), newOutput.c_str());
|
||||
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popChangeOutputFolder", 0), oldSafe.c_str(), tmp.c_str());
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT,
|
||||
ui::getUICString("popChangeOutputFolder", 0),
|
||||
oldSafe.c_str(),
|
||||
tmp.c_str());
|
||||
}
|
||||
else
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popChangeOutputError", 0), newPath.c_str());
|
||||
}
|
||||
|
||||
std::string cfg::getPathDefinition(const uint64_t& tid)
|
||||
std::string cfg::getPathDefinition(uint64_t tid)
|
||||
{
|
||||
return pathDefs[tid];
|
||||
}
|
||||
|
||||
void cfg::addPathToFilter(const uint64_t& tid, const std::string& _p)
|
||||
void cfg::addPathToFilter(uint64_t tid, const std::string &_p)
|
||||
{
|
||||
char outpath[128];
|
||||
sprintf(outpath, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid);
|
||||
|
|
@ -163,7 +186,7 @@ void cfg::resetConfig()
|
|||
cfg::config["autoUpload"] = false;
|
||||
}
|
||||
|
||||
static inline bool textToBool(const std::string& _txt)
|
||||
static inline bool textToBool(const std::string &_txt)
|
||||
{
|
||||
return _txt == _true_ ? true : false;
|
||||
}
|
||||
|
|
@ -175,7 +198,7 @@ static inline std::string boolToText(bool _b)
|
|||
|
||||
static inline std::string sortTypeText()
|
||||
{
|
||||
switch(cfg::sortType)
|
||||
switch (cfg::sortType)
|
||||
{
|
||||
case cfg::ALPHA:
|
||||
return "ALPHA";
|
||||
|
|
@ -194,7 +217,7 @@ static inline std::string sortTypeText()
|
|||
|
||||
static void loadWorkDirLegacy()
|
||||
{
|
||||
if(fs::fileExists(workDirLegacy))
|
||||
if (fs::fileExists(workDirLegacy))
|
||||
{
|
||||
char tmp[256];
|
||||
memset(tmp, 0, 256);
|
||||
|
|
@ -213,14 +236,14 @@ static void loadWorkDirLegacy()
|
|||
static void loadConfigLegacy()
|
||||
{
|
||||
std::string legacyCfgPath = fs::getWorkDir() + "cfg.bin";
|
||||
if(fs::fileExists(legacyCfgPath))
|
||||
if (fs::fileExists(legacyCfgPath))
|
||||
{
|
||||
FILE *oldCfg = fopen(legacyCfgPath.c_str(), "rb");
|
||||
uint64_t cfgIn = 0;
|
||||
fread(&cfgIn, sizeof(uint64_t), 1, oldCfg);
|
||||
fread(&cfg::sortType, 1, 1, oldCfg);
|
||||
fread(&ui::animScale, sizeof(float), 1, oldCfg);
|
||||
if(ui::animScale == 0)
|
||||
if (ui::animScale == 0)
|
||||
ui::animScale = 3.0f;
|
||||
fclose(oldCfg);
|
||||
|
||||
|
|
@ -244,10 +267,10 @@ static void loadConfigLegacy()
|
|||
static void loadFavoritesLegacy()
|
||||
{
|
||||
std::string legacyFavPath = fs::getWorkDir() + "favorites.txt";
|
||||
if(fs::fileExists(legacyFavPath))
|
||||
if (fs::fileExists(legacyFavPath))
|
||||
{
|
||||
fs::dataFile fav(legacyFavPath);
|
||||
while(fav.readNextLine(false))
|
||||
while (fav.readNextLine(false))
|
||||
cfg::favorites.push_back(strtoul(fav.getLine().c_str(), NULL, 16));
|
||||
fav.close();
|
||||
fs::delfile(legacyFavPath);
|
||||
|
|
@ -257,10 +280,10 @@ static void loadFavoritesLegacy()
|
|||
static void loadBlacklistLegacy()
|
||||
{
|
||||
std::string legacyBlPath = fs::getWorkDir() + "blacklist.txt";
|
||||
if(fs::fileExists(legacyBlPath))
|
||||
if (fs::fileExists(legacyBlPath))
|
||||
{
|
||||
fs::dataFile bl(legacyBlPath);
|
||||
while(bl.readNextLine(false))
|
||||
while (bl.readNextLine(false))
|
||||
cfg::blacklist.push_back(strtoul(bl.getLine().c_str(), NULL, 16));
|
||||
bl.close();
|
||||
fs::delfile(legacyBlPath);
|
||||
|
|
@ -270,10 +293,10 @@ static void loadBlacklistLegacy()
|
|||
static void loadTitleDefsLegacy()
|
||||
{
|
||||
std::string titleDefLegacy = fs::getWorkDir() + "titleDefs.txt";
|
||||
if(fs::fileExists(titleDefLegacy))
|
||||
if (fs::fileExists(titleDefLegacy))
|
||||
{
|
||||
fs::dataFile getPaths(titleDefLegacy);
|
||||
while(getPaths.readNextLine(true))
|
||||
while (getPaths.readNextLine(true))
|
||||
{
|
||||
uint64_t tid = strtoul(getPaths.getName().c_str(), NULL, 16);
|
||||
pathDefs[tid] = getPaths.getNextValueStr();
|
||||
|
|
@ -286,10 +309,10 @@ static void loadTitleDefsLegacy()
|
|||
//Oops
|
||||
static void loadTitleDefs()
|
||||
{
|
||||
if(fs::fileExists(titleDefPath))
|
||||
if (fs::fileExists(titleDefPath))
|
||||
{
|
||||
fs::dataFile getPaths(titleDefPath);
|
||||
while(getPaths.readNextLine(true))
|
||||
while (getPaths.readNextLine(true))
|
||||
{
|
||||
uint64_t tid = strtoul(getPaths.getName().c_str(), NULL, 16);
|
||||
pathDefs[tid] = getPaths.getNextValueStr();
|
||||
|
|
@ -302,25 +325,25 @@ static void loadDriveConfig()
|
|||
// Start Google Drive
|
||||
fs::dirList cfgList("/config/JKSV/", true);
|
||||
std::string clientSecretPath;
|
||||
for(unsigned i = 0; i < cfgList.getCount(); i++)
|
||||
for (unsigned i = 0; i < cfgList.getCount(); i++)
|
||||
{
|
||||
std::string itemName = cfgList.getItem(i);
|
||||
if(itemName.find("client_secret") != itemName.npos)
|
||||
if (itemName.find("client_secret") != itemName.npos)
|
||||
{
|
||||
clientSecretPath = "/config/JKSV/" + cfgList.getItem(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!clientSecretPath.empty())
|
||||
if (!clientSecretPath.empty())
|
||||
{
|
||||
json_object *installed, *clientID, *clientSecret, *driveJSON = json_object_from_file(clientSecretPath.c_str());
|
||||
if (driveJSON)
|
||||
if (driveJSON)
|
||||
{
|
||||
if(json_object_object_get_ex(driveJSON, "installed", &installed))
|
||||
if (json_object_object_get_ex(driveJSON, "installed", &installed))
|
||||
{
|
||||
if(json_object_object_get_ex(installed, "client_id", &clientID)
|
||||
&& json_object_object_get_ex(installed, "client_secret", &clientSecret))
|
||||
if (json_object_object_get_ex(installed, "client_id", &clientID) &&
|
||||
json_object_object_get_ex(installed, "client_secret", &clientSecret))
|
||||
{
|
||||
cfg::driveClientID = json_object_get_string(clientID);
|
||||
cfg::driveClientSecret = json_object_get_string(clientSecret);
|
||||
|
|
@ -336,16 +359,20 @@ static void loadDriveConfig()
|
|||
json_object *origin, *basepath, *username, *password;
|
||||
if (webdavJSON)
|
||||
{
|
||||
if (json_object_object_get_ex(webdavJSON, "origin", &origin)) {
|
||||
if (json_object_object_get_ex(webdavJSON, "origin", &origin))
|
||||
{
|
||||
cfg::webdavOrigin = json_object_get_string(origin);
|
||||
}
|
||||
if (json_object_object_get_ex(webdavJSON, "basepath", &basepath)) {
|
||||
if (json_object_object_get_ex(webdavJSON, "basepath", &basepath))
|
||||
{
|
||||
cfg::webdavBasePath = json_object_get_string(basepath);
|
||||
}
|
||||
if (json_object_object_get_ex(webdavJSON, "username", &username)) {
|
||||
if (json_object_object_get_ex(webdavJSON, "username", &username))
|
||||
{
|
||||
cfg::webdavUser = json_object_get_string(username);
|
||||
}
|
||||
if (json_object_object_get_ex(webdavJSON, "password", &password)) {
|
||||
if (json_object_object_get_ex(webdavJSON, "password", &password))
|
||||
{
|
||||
cfg::webdavPassword = json_object_get_string(password);
|
||||
}
|
||||
json_object_put(webdavJSON);
|
||||
|
|
@ -362,15 +389,15 @@ void cfg::loadConfig()
|
|||
loadTitleDefsLegacy();
|
||||
loadTitleDefs();
|
||||
|
||||
if(fs::fileExists(cfgPath))
|
||||
if (fs::fileExists(cfgPath))
|
||||
{
|
||||
fs::dataFile cfgRead(cfgPath);
|
||||
while(cfgRead.readNextLine(true))
|
||||
while (cfgRead.readNextLine(true))
|
||||
{
|
||||
std::string varName = cfgRead.getName();
|
||||
if(cfgStrings.find(varName) != cfgStrings.end())
|
||||
if (cfgStrings.find(varName) != cfgStrings.end())
|
||||
{
|
||||
switch(cfgStrings[varName])
|
||||
switch (cfgStrings[varName])
|
||||
{
|
||||
case 0:
|
||||
fs::setWorkDir(cfgRead.getNextValueStr());
|
||||
|
|
@ -429,37 +456,37 @@ void cfg::loadConfig()
|
|||
break;
|
||||
|
||||
case 14:
|
||||
{
|
||||
std::string getSort = cfgRead.getNextValueStr();
|
||||
if(getSort == "ALPHA")
|
||||
cfg::sortType = cfg::ALPHA;
|
||||
else if(getSort == "MOST_PLAYED")
|
||||
cfg::sortType = cfg::MOST_PLAYED;
|
||||
else
|
||||
cfg::sortType = cfg::LAST_PLAYED;
|
||||
}
|
||||
break;
|
||||
{
|
||||
std::string getSort = cfgRead.getNextValueStr();
|
||||
if (getSort == "ALPHA")
|
||||
cfg::sortType = cfg::ALPHA;
|
||||
else if (getSort == "MOST_PLAYED")
|
||||
cfg::sortType = cfg::MOST_PLAYED;
|
||||
else
|
||||
cfg::sortType = cfg::LAST_PLAYED;
|
||||
}
|
||||
break;
|
||||
|
||||
case 15:
|
||||
{
|
||||
std::string animFloat = cfgRead.getNextValueStr();
|
||||
ui::animScale = strtof(animFloat.c_str(), NULL);
|
||||
}
|
||||
break;
|
||||
{
|
||||
std::string animFloat = cfgRead.getNextValueStr();
|
||||
ui::animScale = strtof(animFloat.c_str(), NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
{
|
||||
std::string tid = cfgRead.getNextValueStr();
|
||||
cfg::favorites.push_back(strtoul(tid.c_str(), NULL, 16));
|
||||
}
|
||||
break;
|
||||
{
|
||||
std::string tid = cfgRead.getNextValueStr();
|
||||
cfg::favorites.push_back(strtoul(tid.c_str(), NULL, 16));
|
||||
}
|
||||
break;
|
||||
|
||||
case 17:
|
||||
{
|
||||
std::string tid = cfgRead.getNextValueStr();
|
||||
cfg::blacklist.push_back(strtoul(tid.c_str(), NULL, 16));
|
||||
}
|
||||
break;
|
||||
{
|
||||
std::string tid = cfgRead.getNextValueStr();
|
||||
cfg::blacklist.push_back(strtoul(tid.c_str(), NULL, 16));
|
||||
}
|
||||
break;
|
||||
|
||||
case 18:
|
||||
cfg::config["autoName"] = textToBool(cfgRead.getNextValueStr());
|
||||
|
|
@ -485,7 +512,7 @@ void cfg::loadConfig()
|
|||
static void savePathDefs()
|
||||
{
|
||||
FILE *pathOut = fopen(titleDefPath, "w");
|
||||
for(auto& p : pathDefs)
|
||||
for (auto &p : pathDefs)
|
||||
fprintf(pathOut, "0x%016lX = \"%s\"\n", p.first, p.second.c_str());
|
||||
fclose(pathOut);
|
||||
}
|
||||
|
|
@ -511,24 +538,24 @@ void cfg::saveConfig()
|
|||
fprintf(cfgOut, "titleSortType = %s\n", sortTypeText().c_str());
|
||||
fprintf(cfgOut, "animationScale = %f\n", ui::animScale);
|
||||
|
||||
if(!cfg::driveRefreshToken.empty())
|
||||
if (!cfg::driveRefreshToken.empty())
|
||||
fprintf(cfgOut, "driveRefreshToken = %s\n", cfg::driveRefreshToken.c_str());
|
||||
|
||||
if(!cfg::favorites.empty())
|
||||
if (!cfg::favorites.empty())
|
||||
{
|
||||
fprintf(cfgOut, "\n#favorites\n");
|
||||
for(uint64_t& f : cfg::favorites)
|
||||
for (uint64_t &f : cfg::favorites)
|
||||
fprintf(cfgOut, "favorite = 0x%016lX\n", f);
|
||||
}
|
||||
|
||||
if(!cfg::blacklist.empty())
|
||||
if (!cfg::blacklist.empty())
|
||||
{
|
||||
fprintf(cfgOut, "\n#blacklist\n");
|
||||
for(uint64_t& b : cfg::blacklist)
|
||||
for (uint64_t &b : cfg::blacklist)
|
||||
fprintf(cfgOut, "blacklist = 0x%016lX\n", b);
|
||||
}
|
||||
fclose(cfgOut);
|
||||
|
||||
if(!pathDefs.empty())
|
||||
if (!pathDefs.empty())
|
||||
savePathDefs();
|
||||
}
|
||||
|
|
|
|||
496
src/data.cpp
496
src/data.cpp
|
|
@ -1,54 +1,76 @@
|
|||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <switch.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "cfg.h"
|
||||
#include "data.h"
|
||||
#include "file.h"
|
||||
#include "util.h"
|
||||
#include "type.h"
|
||||
#include "cfg.h"
|
||||
#include "util.h"
|
||||
|
||||
//FsSaveDataSpaceId_All doesn't work for SD
|
||||
static const unsigned saveOrder [] = { 0, 1, 2, 3, 4, 100, 101 };
|
||||
namespace
|
||||
{
|
||||
/// @brief This is the string used for when a publisher isn't found in the NACP.
|
||||
constexpr std::string_view STRING_UNKOWN_AUTHOR = "Someone?";
|
||||
|
||||
/// @brief This array holds the order in which to scan save data space IDs since the all pseudo value from libnx doesn't seem to work.
|
||||
constexpr std::array<FsSaveDataSpaceId, 7> ORDER_SAVE_DATA_SPACES = {FsSaveDataSpaceId_System,
|
||||
FsSaveDataSpaceId_User,
|
||||
FsSaveDataSpaceId_SdSystem,
|
||||
FsSaveDataSpaceId_Temporary,
|
||||
FsSaveDataSpaceId_SdUser,
|
||||
FsSaveDataSpaceId_ProperSystem,
|
||||
FsSaveDataSpaceId_SafeMode};
|
||||
|
||||
/// @brief This saves whether or not the System BCAT user was pushed.
|
||||
bool s_systemBCATPushed = false;
|
||||
|
||||
/// @brief This saves whether or not the Temporary save user was pushed.
|
||||
bool s_temporaryPushed = false;
|
||||
} // namespace
|
||||
|
||||
/// @brief External variables I used to track selected user/title.
|
||||
int selUser = 0, selData = 0;
|
||||
|
||||
//User vector
|
||||
/// @brief This vector holds the user instances.
|
||||
std::vector<data::user> data::users;
|
||||
|
||||
//System language
|
||||
/// @brief System language. I don't know why this is here in data?
|
||||
SetLanguage data::sysLang;
|
||||
|
||||
//For other save types
|
||||
static bool sysBCATPushed = false, tempPushed = false;
|
||||
/// @brief This is the map of titleInfo.
|
||||
std::unordered_map<uint64_t, data::titleInfo> data::titles;
|
||||
|
||||
//Sorts titles by sortType
|
||||
static struct
|
||||
{
|
||||
bool operator()(const data::userTitleInfo& a, const data::userTitleInfo& b)
|
||||
{
|
||||
//Favorites override EVERYTHING
|
||||
if(cfg::isFavorite(a.tid) != cfg::isFavorite(b.tid)) return cfg::isFavorite(a.tid);
|
||||
|
||||
switch(cfg::sortType)
|
||||
bool operator()(const data::userTitleInfo &a, const data::userTitleInfo &b)
|
||||
{
|
||||
case cfg::ALPHA:
|
||||
//Favorites override EVERYTHING
|
||||
if (cfg::isFavorite(a.tid) != cfg::isFavorite(b.tid))
|
||||
return cfg::isFavorite(a.tid);
|
||||
|
||||
switch (cfg::sortType)
|
||||
{
|
||||
case cfg::ALPHA:
|
||||
{
|
||||
std::string titleA = data::getTitleNameByTID(a.tid);
|
||||
std::string titleB = data::getTitleNameByTID(b.tid);
|
||||
uint32_t pointA, pointB;
|
||||
for(unsigned i = 0, j = 0; i < titleA.length(); )
|
||||
for (unsigned i = 0, j = 0; i < titleA.length();)
|
||||
{
|
||||
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)
|
||||
if (pointA != pointB)
|
||||
return pointA < pointB;
|
||||
|
||||
i += aCnt;
|
||||
|
|
@ -57,115 +79,185 @@ static struct
|
|||
}
|
||||
break;
|
||||
|
||||
case cfg::MOST_PLAYED:
|
||||
return a.playStats.playtime > b.playStats.playtime;
|
||||
break;
|
||||
case cfg::MOST_PLAYED:
|
||||
return a.playStats.playtime > b.playStats.playtime;
|
||||
break;
|
||||
|
||||
case cfg::LAST_PLAYED:
|
||||
return a.playStats.last_timestamp_user> b.playStats.last_timestamp_user;
|
||||
break;
|
||||
case cfg::LAST_PLAYED:
|
||||
return a.playStats.last_timestamp_user > b.playStats.last_timestamp_user;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} sortTitles;
|
||||
|
||||
//Returns -1 for new
|
||||
static int getUserIndex(const AccountUid& id)
|
||||
static int getUserIndex(AccountUid id)
|
||||
{
|
||||
u128 nId = util::accountUIDToU128(id);
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
if(data::users[i].getUID128() == nId) return i;
|
||||
for (unsigned i = 0; i < data::users.size(); i++)
|
||||
if (data::users[i].getUID128() == nId)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static inline bool accountSystemSaveCheck(const FsSaveDataInfo& _inf)
|
||||
static inline bool accountSystemSaveCheck(const FsSaveDataInfo &_inf)
|
||||
{
|
||||
if(_inf.save_data_type == FsSaveDataType_System && util::accountUIDToU128(_inf.uid) != 0 && !cfg::config["accSysSave"])
|
||||
if (_inf.save_data_type == FsSaveDataType_System && util::accountUIDToU128(_inf.uid) != 0 &&
|
||||
!cfg::config["accSysSave"])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//Minimal init/test to avoid loading and creating things I don't need
|
||||
static bool testMount(const FsSaveDataInfo& _inf)
|
||||
static bool testMount(const FsSaveDataInfo &_inf)
|
||||
{
|
||||
bool ret = false;
|
||||
if(!cfg::config["forceMount"])
|
||||
if (!cfg::config["forceMount"])
|
||||
return true;
|
||||
|
||||
if((ret = fs::mountSave(_inf)))
|
||||
if ((ret = fs::mountSave(_inf)))
|
||||
fs::unmountSave();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void addTitleToList(const uint64_t& tid)
|
||||
/// @brief This version of the function uses the title/application ID to pull the data from the system.
|
||||
/// @param titleID Title/Application ID of the title to add.
|
||||
static void add_title_to_list(uint64_t titleID)
|
||||
{
|
||||
uint64_t outSize = 0;
|
||||
NsApplicationControlData *ctrlData = new NsApplicationControlData;
|
||||
NacpLanguageEntry *ent;
|
||||
Result ctrlRes = nsGetApplicationControlData(NsApplicationControlSource_Storage, tid, ctrlData, sizeof(NsApplicationControlData), &outSize);
|
||||
Result nacpRes = nacpGetLanguageEntry(&ctrlData->nacp, &ent);
|
||||
size_t iconSize = outSize - sizeof(ctrlData->nacp);
|
||||
// This is the output size of the control data.
|
||||
uint64_t dataSize = 0;
|
||||
// This is the size of the icon.
|
||||
size_t iconSize = 0;
|
||||
// Nacp language entry pointer.
|
||||
NacpLanguageEntry *entry = nullptr;
|
||||
|
||||
if(R_SUCCEEDED(ctrlRes) && !(outSize < sizeof(ctrlData->nacp)) && R_SUCCEEDED(nacpRes) && iconSize > 0)
|
||||
// Try to read the control data directly into the map.
|
||||
Result nsError = nsGetApplicationControlData(NsApplicationControlSource_Storage,
|
||||
titleID,
|
||||
&data::titles[titleID].data,
|
||||
sizeof(NsApplicationControlData),
|
||||
&dataSize);
|
||||
|
||||
// At this point, regardless, the title should exist in the map. Using a reference from here on out.
|
||||
data::titleInfo &info = data::titles[titleID];
|
||||
|
||||
// Calc icon size. Not sure this is really needed?
|
||||
iconSize = dataSize - sizeof(NacpStruct);
|
||||
|
||||
// If that failed, run the backup routine and bail.
|
||||
if (R_FAILED(nsError) || dataSize < sizeof(info.data.nacp) || iconSize <= 0 ||
|
||||
R_FAILED(nacpGetLanguageEntry(&info.data.nacp, &entry)))
|
||||
{
|
||||
//Copy nacp
|
||||
memcpy(&data::titles[tid].nacp, &ctrlData->nacp, sizeof(NacpStruct));
|
||||
// Clear the NACP.
|
||||
std::memset(&info.data.nacp, 0x00, sizeof(NacpStruct));
|
||||
|
||||
//Setup 'shortcuts' to strings
|
||||
NacpLanguageEntry *ent;
|
||||
nacpGetLanguageEntry(&data::titles[tid].nacp, &ent);
|
||||
if(strlen(ent->name) == 0)
|
||||
data::titles[tid].title = ctrlData->nacp.lang[SetLanguage_ENUS].name;
|
||||
// Set the title and publisher.
|
||||
info.title = util::getIDStr(titleID);
|
||||
info.author = STRING_UNKOWN_AUTHOR;
|
||||
|
||||
// Check if the title has a path defined in the config.
|
||||
if (cfg::isDefined(titleID))
|
||||
{
|
||||
info.safeTitle = cfg::getPathDefinition(titleID);
|
||||
}
|
||||
else
|
||||
data::titles[tid].title = ent->name;
|
||||
data::titles[tid].author = ent->author;
|
||||
if(cfg::isDefined(tid))
|
||||
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
|
||||
else if((data::titles[tid].safeTitle = util::safeString(ent->name)) == "")
|
||||
data::titles[tid].safeTitle = util::getIDStr(tid);
|
||||
{
|
||||
info.safeTitle = util::getIDStr(titleID);
|
||||
}
|
||||
|
||||
if(cfg::isFavorite(tid))
|
||||
data::titles[tid].fav = true;
|
||||
|
||||
data::titles[tid].icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, ctrlData->icon, iconSize);
|
||||
if(!data::titles[tid].icon)
|
||||
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
|
||||
// Create the icon.
|
||||
std::string idHex = util::getIDStrLower(titleID);
|
||||
info.icon = util::createIconGeneric(idHex.c_str(), 32, true);
|
||||
|
||||
// Bail. Do not continue. We're done.
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&data::titles[tid].nacp, 0, sizeof(NacpStruct));
|
||||
data::titles[tid].title = util::getIDStr(tid);
|
||||
data::titles[tid].author = "Someone?";
|
||||
if(cfg::isDefined(tid))
|
||||
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
|
||||
// Check to make sure the title isn't blank. If it is, use English.
|
||||
if (std::char_traits<char>::length(entry->name) == 0)
|
||||
{
|
||||
info.title = info.data.nacp.lang[SetLanguage_ENUS].name;
|
||||
}
|
||||
else
|
||||
data::titles[tid].safeTitle = util::getIDStr(tid);
|
||||
{
|
||||
info.title = entry->name;
|
||||
}
|
||||
|
||||
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
|
||||
// Check the same for author/publisher.
|
||||
if (std::char_traits<char>::length(entry->author) == 0)
|
||||
{
|
||||
info.author = info.data.nacp.lang[SetLanguage_ENUS].author;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.author = entry->author;
|
||||
}
|
||||
|
||||
// Load the icon from the control data.
|
||||
info.icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, info.data.icon, iconSize);
|
||||
|
||||
// Make sure to save that the title has valid control data.
|
||||
info.hasControlData = true;
|
||||
}
|
||||
delete ctrlData;
|
||||
}
|
||||
|
||||
static inline bool titleIsLoaded(const uint64_t& tid)
|
||||
{
|
||||
auto findTid = data::titles.find(tid);
|
||||
|
||||
return findTid == data::titles.end() ? false : true;
|
||||
}
|
||||
|
||||
static void loadUserAccounts()
|
||||
{
|
||||
s32 total = 0;
|
||||
AccountUid *uids = new AccountUid[8];
|
||||
if(R_SUCCEEDED(accountListAllUsers(uids, 8, &total)))
|
||||
// The following is universal whether the title has control data or not.
|
||||
// Set the safe path title. Note: I hate the second else if statement, but screw it. Rewrite avoids this kind of stuff.
|
||||
if (cfg::isDefined(titleID))
|
||||
{
|
||||
for(int i = 0; i < total; i++)
|
||||
data::users.emplace_back(uids[i], "", "");
|
||||
info.safeTitle = cfg::getPathDefinition(titleID);
|
||||
}
|
||||
else if ((info.safeTitle = util::safeString(entry->name)) == "")
|
||||
{
|
||||
info.safeTitle = util::getIDStr(titleID);
|
||||
}
|
||||
|
||||
// Favorite check.
|
||||
if (cfg::isFavorite(titleID))
|
||||
{
|
||||
info.fav = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Adds a title to the map using the application ID and cached control data.
|
||||
/// @param titleID Application ID of the title.
|
||||
/// @param data Reference to the data to use.
|
||||
static void add_title_to_list(uint64_t titleID, NsApplicationControlData &data)
|
||||
{
|
||||
// Start by memcpy'ing the data over.
|
||||
std::memcpy(&data::titles[titleID].data, &data, sizeof(NsApplicationControlData));
|
||||
|
||||
// Since this function is always being fed cached data, we're going to assume everything else is good.
|
||||
}
|
||||
|
||||
|
||||
static inline bool titleIsLoaded(uint64_t titleID)
|
||||
{
|
||||
return data::titles.find(titleID) != data::titles.end();
|
||||
}
|
||||
|
||||
static void loadUserAccounts(void)
|
||||
{
|
||||
// Total accounts listed.
|
||||
int total = 0;
|
||||
// Switch has eight accounts max.
|
||||
AccountUid accounts[8] = {0};
|
||||
|
||||
if (R_FAILED(accountListAllUsers(accounts, 8, &total)))
|
||||
{
|
||||
// Rewrite logs this.
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < total; i++)
|
||||
{
|
||||
// Maybe to do: This looks stupid. Overload constructors?
|
||||
data::users.emplace_back(accounts[i], "", "");
|
||||
}
|
||||
delete[] uids;
|
||||
}
|
||||
|
||||
//This can load titles installed without having save data
|
||||
|
|
@ -173,56 +265,96 @@ static void loadTitlesFromRecords()
|
|||
{
|
||||
NsApplicationRecord nsRecord;
|
||||
int32_t entryCount = 0, recordOffset = 0;
|
||||
while(R_SUCCEEDED(nsListApplicationRecord(&nsRecord, 1, recordOffset++, &entryCount)) && entryCount > 0)
|
||||
while (R_SUCCEEDED(nsListApplicationRecord(&nsRecord, 1, recordOffset++, &entryCount)) && entryCount > 0)
|
||||
{
|
||||
if(!titleIsLoaded(nsRecord.application_id))
|
||||
addTitleToList(nsRecord.application_id);
|
||||
if (!titleIsLoaded(nsRecord.application_id))
|
||||
{
|
||||
add_title_to_list(nsRecord.application_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void importSVIs()
|
||||
static void import_svi_files(void)
|
||||
{
|
||||
std::string sviDir = fs::getWorkDir() + "svi/";
|
||||
fs::dirList sviList(sviDir);
|
||||
if(sviList.getCount() > 0)
|
||||
// This is the path used. JKSV master was written before fslib.
|
||||
std::string sviPath = fs::getWorkDir() + "svi";
|
||||
|
||||
// Get the listing and check to make sure there was actually something in it.
|
||||
fs::dirList sviList(sviPath);
|
||||
if (sviList.getCount() <= 0)
|
||||
{
|
||||
for(unsigned i = 0; i < sviList.getCount(); i++)
|
||||
// Just return and don't do anything.
|
||||
return;
|
||||
}
|
||||
|
||||
// Loop through the listing and load them all.
|
||||
for (unsigned int i = 0; i < sviList.getCount(); i++)
|
||||
{
|
||||
// Full path to the file.
|
||||
std::string fullPath = sviPath + "/" + sviList.getItem(i);
|
||||
|
||||
// Grab the size of the SVI before continuing.
|
||||
size_t sviSize = fs::fsize(fullPath);
|
||||
|
||||
// Application ID
|
||||
uint64_t applicationID = 0;
|
||||
// Language entry.
|
||||
NacpLanguageEntry *entry = nullptr;
|
||||
// Icon size.
|
||||
size_t iconSize = 0;
|
||||
|
||||
// Open the file and read the application ID.
|
||||
std::FILE *sviFile = std::fopen(sviPath.c_str(), "rb");
|
||||
std::fread(&applicationID, 1, sizeof(uint64_t), sviFile);
|
||||
|
||||
// If it already exists in the map, just continue.
|
||||
if (titleIsLoaded(applicationID))
|
||||
{
|
||||
uint64_t tid = 0;
|
||||
NacpStruct *nacp = new NacpStruct;
|
||||
NacpLanguageEntry *ent;
|
||||
std::string sviPath = fs::getWorkDir() + "svi/" + sviList.getItem(i);
|
||||
|
||||
size_t iconSize = fs::fsize(sviPath) - (sizeof(uint64_t) + sizeof(NacpStruct));
|
||||
uint8_t *iconBuffer = new uint8_t[iconSize];
|
||||
FILE *sviIn = fopen(sviPath.c_str(), "rb");
|
||||
fread(&tid, sizeof(uint64_t), 1, sviIn);
|
||||
fread(nacp, sizeof(NacpStruct), 1, sviIn);
|
||||
fread(iconBuffer, 1, iconSize, sviIn);
|
||||
|
||||
if(!titleIsLoaded(tid))
|
||||
{
|
||||
nacpGetLanguageEntry(nacp, &ent);
|
||||
memcpy(&data::titles[tid].nacp, nacp, sizeof(NacpStruct));
|
||||
data::titles[tid].title = ent->name;
|
||||
data::titles[tid].author = ent->author;
|
||||
if(cfg::isDefined(tid))
|
||||
data::titles[tid].safeTitle = cfg::getPathDefinition(tid);
|
||||
else if((data::titles[tid].safeTitle = util::safeString(ent->name)) == "")
|
||||
data::titles[tid].safeTitle = util::getIDStr(tid);
|
||||
|
||||
if(cfg::isFavorite(tid))
|
||||
data::titles[tid].fav = true;
|
||||
|
||||
if(!data::titles[tid].icon && iconSize > 0)
|
||||
data::titles[tid].icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, iconBuffer, iconSize);
|
||||
else if(!data::titles[tid].icon && iconSize == 0)
|
||||
data::titles[tid].icon = util::createIconGeneric(util::getIDStrLower(tid).c_str(), 32, true);
|
||||
}
|
||||
delete nacp;
|
||||
delete[] iconBuffer;
|
||||
fclose(sviIn);
|
||||
std::fclose(sviFile);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Read the NACP data into the map directly.
|
||||
std::fread(&data::titles[applicationID].data.nacp, 1, sizeof(NacpStruct), sviFile);
|
||||
|
||||
// Calculate the icon size and read that too. The ControlData has memory set aside for the icon anyway.
|
||||
iconSize = fs::fsize(fullPath) - (sizeof(uint64_t) + sizeof(NacpStruct));
|
||||
std::fread(&data::titles[applicationID].data.icon, 1, iconSize, sviFile);
|
||||
|
||||
// Think I should be safe to use a reference now?
|
||||
data::titleInfo &info = data::titles[applicationID];
|
||||
|
||||
// Setup the title stuff.
|
||||
if (R_FAILED(nacpGetLanguageEntry(&info.data.nacp, &entry)))
|
||||
{
|
||||
// Default to English.
|
||||
info.title = info.data.nacp.lang[SetLanguage_ENUS].name;
|
||||
info.author = info.data.nacp.lang[SetLanguage_ENUS].author;
|
||||
}
|
||||
else
|
||||
{
|
||||
info.title = entry->name;
|
||||
info.author = entry->author;
|
||||
}
|
||||
|
||||
// Safe path.
|
||||
if (cfg::isDefined(applicationID))
|
||||
{
|
||||
info.safeTitle = cfg::getPathDefinition(applicationID);
|
||||
}
|
||||
else if ((info.safeTitle = util::safeString(info.title)).empty())
|
||||
{
|
||||
info.safeTitle = util::getIDStr(applicationID);
|
||||
}
|
||||
|
||||
// Favorite
|
||||
if (cfg::isFavorite(applicationID))
|
||||
{
|
||||
info.fav = true;
|
||||
}
|
||||
|
||||
// Just going to assume this is good.
|
||||
info.icon = gfx::texMgr->textureLoadFromMem(IMG_FMT_JPG, info.data.icon, iconSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -234,21 +366,25 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
s64 total = 0;
|
||||
|
||||
loadTitlesFromRecords();
|
||||
importSVIs();
|
||||
import_svi_files();
|
||||
|
||||
//Clear titles
|
||||
for(data::user& u : data::users)
|
||||
for (data::user &u : data::users)
|
||||
{
|
||||
u.titleInfo.clear();
|
||||
if(clearUsers)
|
||||
}
|
||||
if (clearUsers)
|
||||
{
|
||||
systemUserCount = 4;
|
||||
for(data::user& u : data::users)
|
||||
for (data::user &u : data::users)
|
||||
{
|
||||
u.delIcon();
|
||||
}
|
||||
data::users.clear();
|
||||
|
||||
loadUserAccounts();
|
||||
sysBCATPushed = false;
|
||||
tempPushed = false;
|
||||
s_systemBCATPushed = false;
|
||||
s_temporaryPushed = false;
|
||||
|
||||
users.emplace_back(util::u128ToAccountUID(3), ui::getUIString("saveTypeMainMenu", 0), "Device");
|
||||
users.emplace_back(util::u128ToAccountUID(2), ui::getUIString("saveTypeMainMenu", 1), "BCAT");
|
||||
|
|
@ -256,27 +392,29 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
users.emplace_back(util::u128ToAccountUID(0), ui::getUIString("saveTypeMainMenu", 3), "System");
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < 7; i++)
|
||||
for (unsigned i = 0; i < 7; i++)
|
||||
{
|
||||
if(R_FAILED(fsOpenSaveDataInfoReader(&it, (FsSaveDataSpaceId)saveOrder[i])))
|
||||
if (R_FAILED(fsOpenSaveDataInfoReader(&it, ORDER_SAVE_DATA_SPACES.at(i))))
|
||||
continue;
|
||||
|
||||
while(R_SUCCEEDED(fsSaveDataInfoReaderRead(&it, &info, 1, &total)) && total != 0)
|
||||
while (R_SUCCEEDED(fsSaveDataInfoReaderRead(&it, &info, 1, &total)) && total != 0)
|
||||
{
|
||||
uint64_t tid = 0;
|
||||
if(info.save_data_type == FsSaveDataType_System || info.save_data_type == FsSaveDataType_SystemBcat)
|
||||
if (info.save_data_type == FsSaveDataType_System || info.save_data_type == FsSaveDataType_SystemBcat)
|
||||
tid = info.system_save_data_id;
|
||||
else
|
||||
tid = info.application_id;
|
||||
|
||||
if(!titleIsLoaded(tid))
|
||||
addTitleToList(tid);
|
||||
if (!titleIsLoaded(tid))
|
||||
{
|
||||
add_title_to_list(tid);
|
||||
}
|
||||
|
||||
//Don't bother with this stuff
|
||||
if(cfg::isBlacklisted(tid) || !accountSystemSaveCheck(info) || !testMount(info))
|
||||
if (cfg::isBlacklisted(tid) || !accountSystemSaveCheck(info) || !testMount(info))
|
||||
continue;
|
||||
|
||||
switch(info.save_data_type)
|
||||
switch (info.save_data_type)
|
||||
{
|
||||
case FsSaveDataType_Bcat:
|
||||
info.uid = util::u128ToAccountUID(2);
|
||||
|
|
@ -288,11 +426,13 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
|
||||
case FsSaveDataType_SystemBcat:
|
||||
info.uid = util::u128ToAccountUID(4);
|
||||
if(!sysBCATPushed)
|
||||
if (!s_systemBCATPushed)
|
||||
{
|
||||
++systemUserCount;
|
||||
sysBCATPushed = true;
|
||||
users.emplace_back(util::u128ToAccountUID(4), ui::getUIString("saveTypeMainMenu", 4), "System BCAT");
|
||||
s_systemBCATPushed = true;
|
||||
users.emplace_back(util::u128ToAccountUID(4),
|
||||
ui::getUIString("saveTypeMainMenu", 4),
|
||||
"System BCAT");
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -302,25 +442,30 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
|
||||
case FsSaveDataType_Temporary:
|
||||
info.uid = util::u128ToAccountUID(6);
|
||||
if(!tempPushed)
|
||||
if (!s_temporaryPushed)
|
||||
{
|
||||
++systemUserCount;
|
||||
tempPushed = true;
|
||||
users.emplace_back(util::u128ToAccountUID(6), ui::getUIString("saveTypeMainMenu", 5), "Temporary");
|
||||
s_temporaryPushed = true;
|
||||
users.emplace_back(util::u128ToAccountUID(6),
|
||||
ui::getUIString("saveTypeMainMenu", 5),
|
||||
"Temporary");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
int u = getUserIndex(info.uid);
|
||||
if(u == -1)
|
||||
if (u == -1)
|
||||
{
|
||||
users.emplace(data::users.end() - systemUserCount, info.uid, "", "");
|
||||
u = getUserIndex(info.uid);
|
||||
}
|
||||
|
||||
PdmPlayStatistics playStats;
|
||||
if(info.save_data_type == FsSaveDataType_Account || info.save_data_type == FsSaveDataType_Device)
|
||||
pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(info.application_id, info.uid, false, &playStats);
|
||||
if (info.save_data_type == FsSaveDataType_Account || info.save_data_type == FsSaveDataType_Device)
|
||||
pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(info.application_id,
|
||||
info.uid,
|
||||
false,
|
||||
&playStats);
|
||||
else
|
||||
memset(&playStats, 0, sizeof(PdmPlayStatistics));
|
||||
users[u].addUserTitleInfo(tid, &info, &playStats);
|
||||
|
|
@ -328,15 +473,15 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
fsSaveDataInfoReaderClose(&it);
|
||||
}
|
||||
|
||||
if(cfg::config["incDev"])
|
||||
if (cfg::config["incDev"])
|
||||
{
|
||||
//Get reference to device save user
|
||||
unsigned devPos = getUserIndex(util::u128ToAccountUID(3));
|
||||
data::user& dev = data::users[devPos];
|
||||
for(unsigned i = 0; i < devPos; i++)
|
||||
data::user &dev = data::users[devPos];
|
||||
for (unsigned i = 0; i < devPos; i++)
|
||||
{
|
||||
//Not needed but makes this easier to read
|
||||
data::user& u = data::users[i];
|
||||
data::user &u = data::users[i];
|
||||
u.titleInfo.insert(u.titleInfo.end(), dev.titleInfo.begin(), dev.titleInfo.end());
|
||||
}
|
||||
}
|
||||
|
|
@ -349,7 +494,7 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
void data::sortUserTitles()
|
||||
{
|
||||
|
||||
for(data::user& u : data::users)
|
||||
for (data::user &u : data::users)
|
||||
std::sort(u.titleInfo.begin(), u.titleInfo.end(), sortTitles);
|
||||
}
|
||||
|
||||
|
|
@ -393,39 +538,39 @@ unsigned data::getCurrentUserTitleInfoIndex()
|
|||
return selData;
|
||||
}
|
||||
|
||||
data::titleInfo *data::getTitleInfoByTID(const uint64_t& tid)
|
||||
data::titleInfo *data::getTitleInfoByTID(const uint64_t &tid)
|
||||
{
|
||||
if(titles.find(tid) != titles.end())
|
||||
if (titles.find(tid) != titles.end())
|
||||
return &titles[tid];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::string data::getTitleNameByTID(const uint64_t& tid)
|
||||
std::string data::getTitleNameByTID(const uint64_t &tid)
|
||||
{
|
||||
return titles[tid].title;
|
||||
}
|
||||
|
||||
std::string data::getTitleSafeNameByTID(const uint64_t& tid)
|
||||
std::string data::getTitleSafeNameByTID(const uint64_t &tid)
|
||||
{
|
||||
return titles[tid].safeTitle;
|
||||
}
|
||||
|
||||
SDL_Texture *data::getTitleIconByTID(const uint64_t& tid)
|
||||
SDL_Texture *data::getTitleIconByTID(const uint64_t &tid)
|
||||
{
|
||||
return titles[tid].icon;
|
||||
}
|
||||
|
||||
int data::getTitleIndexInUser(const data::user& u, const uint64_t& tid)
|
||||
int data::getTitleIndexInUser(const data::user &u, const uint64_t &tid)
|
||||
{
|
||||
for(unsigned i = 0; i < u.titleInfo.size(); i++)
|
||||
for (unsigned i = 0; i < u.titleInfo.size(); i++)
|
||||
{
|
||||
if(u.titleInfo[i].tid == tid)
|
||||
if (u.titleInfo[i].tid == tid)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
data::user::user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName)
|
||||
data::user::user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName)
|
||||
{
|
||||
userID = _id;
|
||||
uID128 = util::accountUIDToU128(_id);
|
||||
|
|
@ -433,11 +578,11 @@ data::user::user(const AccountUid& _id, const std::string& _backupName, const st
|
|||
AccountProfile prof;
|
||||
AccountProfileBase base;
|
||||
|
||||
if(R_SUCCEEDED(accountGetProfile(&prof, userID)) && R_SUCCEEDED(accountProfileGet(&prof, NULL, &base)))
|
||||
if (R_SUCCEEDED(accountGetProfile(&prof, userID)) && R_SUCCEEDED(accountProfileGet(&prof, NULL, &base)))
|
||||
{
|
||||
username = base.nickname;
|
||||
userSafe = util::safeString(username);
|
||||
if(userSafe.empty())
|
||||
if (userSafe.empty())
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, "Acc%08X", (uint32_t)uID128);
|
||||
|
|
@ -462,20 +607,21 @@ data::user::user(const AccountUid& _id, const std::string& _backupName, const st
|
|||
titles.reserve(64);
|
||||
}
|
||||
|
||||
data::user::user(const AccountUid& _id, const std::string& _backupName, const std::string& _safeBackupName, SDL_Texture *img) : user(_id, _backupName, _safeBackupName)
|
||||
data::user::user(AccountUid _id, const std::string &_backupName, const std::string &_safeBackupName, SDL_Texture *img)
|
||||
: user(_id, _backupName, _safeBackupName)
|
||||
{
|
||||
delIcon();
|
||||
userIcon = img;
|
||||
titles.reserve(64);
|
||||
}
|
||||
|
||||
void data::user::setUID(const AccountUid& _id)
|
||||
void data::user::setUID(AccountUid _id)
|
||||
{
|
||||
userID = _id;
|
||||
uID128 = util::accountUIDToU128(_id);
|
||||
}
|
||||
|
||||
void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats)
|
||||
void data::user::addUserTitleInfo(const uint64_t &tid, const FsSaveDataInfo *_saveInfo, const PdmPlayStatistics *_stats)
|
||||
{
|
||||
data::userTitleInfo newInfo;
|
||||
newInfo.tid = tid;
|
||||
|
|
@ -484,7 +630,7 @@ void data::user::addUserTitleInfo(const uint64_t& tid, const FsSaveDataInfo *_sa
|
|||
titleInfo.push_back(newInfo);
|
||||
}
|
||||
|
||||
static const SDL_Color green = {0x00, 0xDD, 0x00, 0xFF};
|
||||
static constexpr SDL_Color green = {0x00, 0xDD, 0x00, 0xFF};
|
||||
|
||||
void data::dispStats()
|
||||
{
|
||||
|
|
@ -493,11 +639,11 @@ void data::dispStats()
|
|||
|
||||
//Easiest/laziest way to do this
|
||||
std::string stats = ui::getUICString("debugStatus", 0) + std::to_string(users.size()) + "\n";
|
||||
for(data::user& u : data::users)
|
||||
for (data::user &u : data::users)
|
||||
stats += u.getUsername() + ": " + std::to_string(u.titleInfo.size()) + "\n";
|
||||
stats += ui::getUICString("debugStatus", 1) + cu->getUsername() + "\n";
|
||||
stats += ui::getUICString("debugStatus", 2) + data::getTitleNameByTID(d->tid) + "\n";
|
||||
stats += ui::getUICString("debugStatus", 3) + data::getTitleSafeNameByTID(d->tid) + "\n";
|
||||
stats += ui::getUICString("debugStatus", 4) + std::to_string(cfg::sortType) + "\n";
|
||||
gfx::drawTextf(NULL, 16, 2, 2, &green, stats.c_str());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
382
src/fs.cpp
382
src/fs.cpp
|
|
@ -1,8 +1,8 @@
|
|||
#include <switch.h>
|
||||
#include <string>
|
||||
#include <switch.h>
|
||||
|
||||
#include "fs.h"
|
||||
#include "cfg.h"
|
||||
#include "fs.h"
|
||||
#include "util.h"
|
||||
|
||||
static std::string wd = "sdmc:/JKSV/";
|
||||
|
|
@ -22,65 +22,65 @@ void fs::init()
|
|||
fs::logOpen();
|
||||
}
|
||||
|
||||
bool fs::mountSave(const FsSaveDataInfo& _m)
|
||||
bool fs::mountSave(const FsSaveDataInfo &_m)
|
||||
{
|
||||
Result svOpen;
|
||||
FsSaveDataAttribute attr = {0};
|
||||
switch(_m.save_data_type)
|
||||
switch (_m.save_data_type)
|
||||
{
|
||||
case FsSaveDataType_System:
|
||||
case FsSaveDataType_SystemBcat:
|
||||
{
|
||||
attr.uid = _m.uid;
|
||||
attr.system_save_data_id = _m.system_save_data_id;
|
||||
attr.save_data_type = _m.save_data_type;
|
||||
svOpen = fsOpenSaveDataFileSystemBySystemSaveDataId(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
{
|
||||
attr.uid = _m.uid;
|
||||
attr.system_save_data_id = _m.system_save_data_id;
|
||||
attr.save_data_type = _m.save_data_type;
|
||||
svOpen = fsOpenSaveDataFileSystemBySystemSaveDataId(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Account:
|
||||
{
|
||||
attr.uid = _m.uid;
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = _m.save_data_type;
|
||||
attr.save_data_rank = _m.save_data_rank;
|
||||
attr.save_data_index = _m.save_data_index;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
{
|
||||
attr.uid = _m.uid;
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = _m.save_data_type;
|
||||
attr.save_data_rank = _m.save_data_rank;
|
||||
attr.save_data_index = _m.save_data_index;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = FsSaveDataType_Device;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = FsSaveDataType_Device;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = FsSaveDataType_Bcat;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = FsSaveDataType_Bcat;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = FsSaveDataType_Cache;
|
||||
attr.save_data_index = _m.save_data_index;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = FsSaveDataType_Cache;
|
||||
attr.save_data_index = _m.save_data_index;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Temporary:
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = _m.save_data_type;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
{
|
||||
attr.application_id = _m.application_id;
|
||||
attr.save_data_type = _m.save_data_type;
|
||||
svOpen = fsOpenSaveDataFileSystem(&sv, (FsSaveDataSpaceId)_m.save_data_space_id, &attr);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
svOpen = 1;
|
||||
|
|
@ -90,11 +90,11 @@ bool fs::mountSave(const FsSaveDataInfo& _m)
|
|||
return R_SUCCEEDED(svOpen) && fsdevMountDevice("sv", sv) != -1;
|
||||
}
|
||||
|
||||
bool fs::commitToDevice(const std::string& dev)
|
||||
bool fs::commitToDevice(const std::string &dev)
|
||||
{
|
||||
bool ret = true;
|
||||
Result res = fsdevCommitDevice(dev.c_str());
|
||||
if(R_FAILED(res))
|
||||
if (R_FAILED(res))
|
||||
{
|
||||
fs::logWrite("Error committing file to device -> 0x%X\n", res);
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popErrorCommittingFile", 0));
|
||||
|
|
@ -103,31 +103,37 @@ bool fs::commitToDevice(const std::string& dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::string fs::getWorkDir() { return wd; }
|
||||
std::string fs::getWorkDir()
|
||||
{
|
||||
return wd;
|
||||
}
|
||||
|
||||
void fs::setWorkDir(const std::string& _w) { wd = _w; }
|
||||
void fs::setWorkDir(const std::string &_w)
|
||||
{
|
||||
wd = _w;
|
||||
}
|
||||
|
||||
|
||||
void fs::loadPathFilters(const uint64_t& tid)
|
||||
void fs::loadPathFilters(uint64_t tid)
|
||||
{
|
||||
char path[256];
|
||||
sprintf(path, "sdmc:/config/JKSV/0x%016lX_filter.txt", tid);
|
||||
if(fs::fileExists(path))
|
||||
if (fs::fileExists(path))
|
||||
{
|
||||
fs::dataFile filter(path);
|
||||
while(filter.readNextLine(false))
|
||||
while (filter.readNextLine(false))
|
||||
pathFilter.push_back(filter.getLine());
|
||||
}
|
||||
}
|
||||
|
||||
bool fs::pathIsFiltered(const std::string& _path)
|
||||
bool fs::pathIsFiltered(const std::string &_path)
|
||||
{
|
||||
if(pathFilter.empty())
|
||||
if (pathFilter.empty())
|
||||
return false;
|
||||
|
||||
for(std::string& _p : pathFilter)
|
||||
for (std::string &_p : pathFilter)
|
||||
{
|
||||
if(_path == _p)
|
||||
if (_path == _p)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -142,16 +148,18 @@ void fs::freePathFilters()
|
|||
void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _uid, threadInfo *t)
|
||||
{
|
||||
data::titleInfo *tinfo = data::getTitleInfoByTID(_tid);
|
||||
if(t)
|
||||
if (t)
|
||||
t->status->setStatus(ui::getUICString("threadStatusCreatingSaveData", 0), tinfo->title.c_str());
|
||||
|
||||
uint16_t cacheIndex = 0;
|
||||
std::string indexStr;
|
||||
if(_type == FsSaveDataType_Cache && !(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 2, 0, NULL)).empty())
|
||||
if (_type == FsSaveDataType_Cache &&
|
||||
!(indexStr = util::getStringInput(SwkbdType_NumPad, "0", ui::getUIString("swkbdSaveIndex", 0), 2, 0, NULL))
|
||||
.empty())
|
||||
cacheIndex = strtoul(indexStr.c_str(), NULL, 10);
|
||||
else if(_type == FsSaveDataType_Cache && indexStr.empty())
|
||||
else if (_type == FsSaveDataType_Cache && indexStr.empty())
|
||||
{
|
||||
if(t)
|
||||
if (t)
|
||||
t->finished = true;
|
||||
return;
|
||||
}
|
||||
|
|
@ -168,54 +176,72 @@ void fs::createSaveData(FsSaveDataType _type, uint64_t _tid, AccountUid _uid, th
|
|||
FsSaveDataCreationInfo crt;
|
||||
memset(&crt, 0, sizeof(FsSaveDataCreationInfo));
|
||||
int64_t saveSize = 0, journalSize = 0;
|
||||
switch(_type)
|
||||
|
||||
// Grab a pointer to the nacp of the title data.
|
||||
NacpStruct *nacp = &tinfo->data.nacp;
|
||||
|
||||
switch (_type)
|
||||
{
|
||||
case FsSaveDataType_Account:
|
||||
saveSize = tinfo->nacp.user_account_save_data_size;
|
||||
journalSize = tinfo->nacp.user_account_save_data_journal_size;
|
||||
break;
|
||||
{
|
||||
saveSize = nacp->user_account_save_data_size;
|
||||
journalSize = nacp->user_account_save_data_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
saveSize = tinfo->nacp.device_save_data_size;
|
||||
journalSize = tinfo->nacp.device_save_data_journal_size;
|
||||
break;
|
||||
{
|
||||
saveSize = nacp->device_save_data_size;
|
||||
journalSize = nacp->device_save_data_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
saveSize = tinfo->nacp.bcat_delivery_cache_storage_size;
|
||||
journalSize = tinfo->nacp.bcat_delivery_cache_storage_size;
|
||||
break;
|
||||
{
|
||||
saveSize = nacp->bcat_delivery_cache_storage_size;
|
||||
journalSize = nacp->bcat_delivery_cache_storage_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
{
|
||||
saveSize = 32 * 1024 * 1024;
|
||||
if(tinfo->nacp.cache_storage_journal_size > tinfo->nacp.cache_storage_data_and_journal_size_max)
|
||||
journalSize = tinfo->nacp.cache_storage_journal_size;
|
||||
if (nacp->cache_storage_journal_size > nacp->cache_storage_data_and_journal_size_max)
|
||||
{
|
||||
journalSize = nacp->cache_storage_journal_size;
|
||||
}
|
||||
else
|
||||
journalSize = tinfo->nacp.cache_storage_data_and_journal_size_max;
|
||||
break;
|
||||
{
|
||||
journalSize = nacp->cache_storage_data_and_journal_size_max;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if(t)
|
||||
{
|
||||
if (t)
|
||||
t->finished = true;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
crt.save_data_size = saveSize;
|
||||
crt.journal_size = journalSize;
|
||||
crt.available_size = 0x4000;
|
||||
crt.owner_id = _type == FsSaveDataType_Bcat ? 0x010000000000000C : tinfo->nacp.save_data_owner_id;
|
||||
crt.owner_id = _type == FsSaveDataType_Bcat ? 0x010000000000000C : nacp->save_data_owner_id;
|
||||
crt.flags = 0;
|
||||
crt.save_data_space_id = FsSaveDataSpaceId_User;
|
||||
|
||||
FsSaveDataMetaInfo meta;
|
||||
memset(&meta, 0, sizeof(FsSaveDataMetaInfo));
|
||||
if(_type != FsSaveDataType_Bcat)
|
||||
if (_type != FsSaveDataType_Bcat)
|
||||
{
|
||||
meta.size = 0x40060;
|
||||
meta.type = FsSaveDataMetaType_Thumbnail;
|
||||
}
|
||||
|
||||
Result res = 0;
|
||||
if(R_SUCCEEDED(res = fsCreateSaveDataFileSystem(&attr, &crt, &meta)))
|
||||
if (R_SUCCEEDED(res = fsCreateSaveDataFileSystem(&attr, &crt, &meta)))
|
||||
{
|
||||
util::createTitleDirectoryByTID(_tid);
|
||||
data::loadUsersTitles(false);
|
||||
|
|
@ -248,14 +274,15 @@ void fs::createSaveDataThreaded(FsSaveDataType _type, uint64_t _tid, AccountUid
|
|||
|
||||
bool fs::extendSaveData(const data::userTitleInfo *tinfo, uint64_t extSize, threadInfo *t)
|
||||
{
|
||||
if(t)
|
||||
t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0), data::getTitleNameByTID(tinfo->tid).c_str());
|
||||
if (t)
|
||||
t->status->setStatus(ui::getUICString("threadStatusExtendingSaveData", 0),
|
||||
data::getTitleNameByTID(tinfo->tid).c_str());
|
||||
|
||||
uint64_t journal = fs::getJournalSizeMax(tinfo);
|
||||
uint64_t saveID = tinfo->saveInfo.save_data_id;
|
||||
uint64_t saveID = tinfo->saveInfo.save_data_id;
|
||||
FsSaveDataSpaceId space = (FsSaveDataSpaceId)tinfo->saveInfo.save_data_space_id;
|
||||
Result res = 0;
|
||||
if(R_FAILED((res = fsExtendSaveDataFileSystem(space, saveID, extSize, journal))))
|
||||
if (R_FAILED((res = fsExtendSaveDataFileSystem(space, saveID, extSize, journal))))
|
||||
{
|
||||
int64_t totalSize = 0;
|
||||
fs::mountSave(tinfo->saveInfo);
|
||||
|
|
@ -290,30 +317,48 @@ uint64_t fs::getJournalSize(const data::userTitleInfo *tinfo)
|
|||
{
|
||||
uint64_t ret = 0;
|
||||
data::titleInfo *t = data::getTitleInfoByTID(tinfo->tid);
|
||||
switch(tinfo->saveInfo.save_data_type)
|
||||
|
||||
// NACP pointer.
|
||||
NacpStruct *nacp = &t->data.nacp;
|
||||
|
||||
switch (tinfo->saveInfo.save_data_type)
|
||||
{
|
||||
case FsSaveDataType_Account:
|
||||
ret = t->nacp.user_account_save_data_journal_size;
|
||||
break;
|
||||
{
|
||||
ret = nacp->user_account_save_data_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
ret = t->nacp.device_save_data_journal_size;
|
||||
break;
|
||||
{
|
||||
ret = nacp->device_save_data_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
ret = t->nacp.bcat_delivery_cache_storage_size;
|
||||
break;
|
||||
{
|
||||
ret = nacp->bcat_delivery_cache_storage_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
if(t->nacp.cache_storage_journal_size > 0)
|
||||
ret = t->nacp.cache_storage_journal_size;
|
||||
{
|
||||
if (nacp->cache_storage_journal_size > 0)
|
||||
{
|
||||
ret = nacp->cache_storage_journal_size;
|
||||
}
|
||||
else
|
||||
ret = t->nacp.cache_storage_data_and_journal_size_max;
|
||||
break;
|
||||
{
|
||||
ret = nacp->cache_storage_data_and_journal_size_max;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
ret = BUFF_SIZE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -322,37 +367,51 @@ uint64_t fs::getJournalSizeMax(const data::userTitleInfo *tinfo)
|
|||
{
|
||||
uint64_t ret = 0;
|
||||
data::titleInfo *extend = data::getTitleInfoByTID(tinfo->tid);
|
||||
switch(tinfo->saveInfo.save_data_type)
|
||||
|
||||
// NACP pointer
|
||||
NacpStruct *nacp = &extend->data.nacp;
|
||||
|
||||
switch (tinfo->saveInfo.save_data_type)
|
||||
{
|
||||
case FsSaveDataType_Account:
|
||||
if(extend->nacp.user_account_save_data_journal_size_max > extend->nacp.user_account_save_data_journal_size)
|
||||
ret = extend->nacp.user_account_save_data_journal_size_max;
|
||||
{
|
||||
if (nacp->user_account_save_data_journal_size_max > nacp->user_account_save_data_journal_size)
|
||||
ret = nacp->user_account_save_data_journal_size_max;
|
||||
else
|
||||
ret = extend->nacp.user_account_save_data_journal_size;
|
||||
break;
|
||||
ret = nacp->user_account_save_data_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
ret = extend->nacp.bcat_delivery_cache_storage_size;
|
||||
break;
|
||||
{
|
||||
ret = nacp->bcat_delivery_cache_storage_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
if(extend->nacp.cache_storage_data_and_journal_size_max > extend->nacp.cache_storage_journal_size)
|
||||
ret = extend->nacp.cache_storage_data_and_journal_size_max;
|
||||
{
|
||||
if (nacp->cache_storage_data_and_journal_size_max > nacp->cache_storage_journal_size)
|
||||
ret = nacp->cache_storage_data_and_journal_size_max;
|
||||
else
|
||||
ret = extend->nacp.cache_storage_journal_size;
|
||||
break;
|
||||
ret = nacp->cache_storage_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
if(extend->nacp.device_save_data_journal_size_max > extend->nacp.device_save_data_journal_size)
|
||||
ret = extend->nacp.device_save_data_journal_size_max;
|
||||
{
|
||||
if (nacp->device_save_data_journal_size_max > nacp->device_save_data_journal_size)
|
||||
ret = nacp->device_save_data_journal_size_max;
|
||||
else
|
||||
ret = extend->nacp.device_save_data_journal_size;
|
||||
break;
|
||||
ret = nacp->device_save_data_journal_size;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
//will just fail
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -373,7 +432,7 @@ void fs::wipeSave()
|
|||
|
||||
void fs::createNewBackup(void *a)
|
||||
{
|
||||
if(!fs::dirNotEmpty("sv:/"))
|
||||
if (!fs::dirNotEmpty("sv:/"))
|
||||
{
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popSaveIsEmpty", 0));
|
||||
return;
|
||||
|
|
@ -387,43 +446,39 @@ void fs::createNewBackup(void *a)
|
|||
|
||||
std::string out;
|
||||
|
||||
if(held & HidNpadButton_R || cfg::config["autoName"])
|
||||
if (held & HidNpadButton_R || cfg::config["autoName"])
|
||||
out = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
||||
else if(held & HidNpadButton_L)
|
||||
else if (held & HidNpadButton_L)
|
||||
out = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YDM);
|
||||
else if(held & HidNpadButton_ZL)
|
||||
else if (held & HidNpadButton_ZL)
|
||||
out = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE);
|
||||
else
|
||||
{
|
||||
const std::string dict[] =
|
||||
{
|
||||
util::getDateTime(util::DATE_FMT_YMD),
|
||||
util::getDateTime(util::DATE_FMT_YDM),
|
||||
util::getDateTime(util::DATE_FMT_HOYSTE),
|
||||
util::getDateTime(util::DATE_FMT_JHK),
|
||||
util::getDateTime(util::DATE_FMT_ASC),
|
||||
u->getUsernameSafe(),
|
||||
t->safeTitle,
|
||||
util::generateAbbrev(d->tid),
|
||||
".zip"
|
||||
};
|
||||
const std::string dict[] = {util::getDateTime(util::DATE_FMT_YMD),
|
||||
util::getDateTime(util::DATE_FMT_YDM),
|
||||
util::getDateTime(util::DATE_FMT_HOYSTE),
|
||||
util::getDateTime(util::DATE_FMT_JHK),
|
||||
util::getDateTime(util::DATE_FMT_ASC),
|
||||
u->getUsernameSafe(),
|
||||
t->safeTitle,
|
||||
util::generateAbbrev(d->tid),
|
||||
".zip"};
|
||||
std::string defaultText = u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
||||
out = util::getStringInput(SwkbdType_QWERTY, defaultText, ui::getUIString("swkbdEnterName", 0), 64, 9, dict);
|
||||
out = util::safeString(out);
|
||||
}
|
||||
|
||||
if(!out.empty())
|
||||
if (!out.empty())
|
||||
{
|
||||
std::string ext = util::getExtensionFromString(out);
|
||||
std::string path = util::generatePathByTID(d->tid) + out;
|
||||
if(cfg::config["zip"] || ext == "zip")
|
||||
if (cfg::config["zip"] || ext == "zip")
|
||||
{
|
||||
if(ext != "zip")//data::zip is on but extension is not zip
|
||||
if (ext != "zip") //data::zip is on but extension is not zip
|
||||
path += ".zip";
|
||||
|
||||
zipFile zip = zipOpen64(path.c_str(), 0);
|
||||
fs::copyDirToZipThreaded("sv:/", zip, false, 0);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -440,14 +495,14 @@ void fs::overwriteBackup(void *a)
|
|||
threadInfo *t = (threadInfo *)a;
|
||||
std::string *dst = (std::string *)t->argPtr;
|
||||
bool saveHasFiles = fs::dirNotEmpty("sv:/");
|
||||
if(fs::isDir(*dst) && saveHasFiles)
|
||||
if (fs::isDir(*dst) && saveHasFiles)
|
||||
{
|
||||
fs::delDir(*dst);
|
||||
fs::mkDir(*dst);
|
||||
dst->append("/");
|
||||
fs::copyDirToDirThreaded("sv:/", *dst);
|
||||
}
|
||||
else if(!fs::isDir(*dst) && util::getExtensionFromString(*dst) == "zip" && saveHasFiles)
|
||||
else if (!fs::isDir(*dst) && util::getExtensionFromString(*dst) == "zip" && saveHasFiles)
|
||||
{
|
||||
fs::delfile(*dst);
|
||||
zipFile zip = zipOpen64(dst->c_str(), 0);
|
||||
|
|
@ -463,34 +518,36 @@ void fs::restoreBackup(void *a)
|
|||
std::string *restore = (std::string *)t->argPtr;
|
||||
data::user *u = data::getCurrentUser();
|
||||
data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo();
|
||||
if((utinfo->saveInfo.save_data_type != FsSaveDataType_System || cfg::config["sysSaveWrite"]))
|
||||
if ((utinfo->saveInfo.save_data_type != FsSaveDataType_System || cfg::config["sysSaveWrite"]))
|
||||
{
|
||||
bool saveHasFiles = fs::dirNotEmpty("sv:/");
|
||||
if(cfg::config["autoBack"] && cfg::config["zip"] && saveHasFiles)
|
||||
if (cfg::config["autoBack"] && cfg::config["zip"] && saveHasFiles)
|
||||
{
|
||||
std::string autoZip = util::generatePathByTID(utinfo->tid) + "/AUTO " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
|
||||
std::string autoZip = util::generatePathByTID(utinfo->tid) + "/AUTO " + u->getUsernameSafe() + " - " +
|
||||
util::getDateTime(util::DATE_FMT_YMD) + ".zip";
|
||||
zipFile zip = zipOpen64(autoZip.c_str(), 0);
|
||||
fs::copyDirToZipThreaded("sv:/", zip, false, 0);
|
||||
}
|
||||
else if(cfg::config["autoBack"] && saveHasFiles)
|
||||
else if (cfg::config["autoBack"] && saveHasFiles)
|
||||
{
|
||||
std::string autoFolder = util::generatePathByTID(utinfo->tid) + "/AUTO - " + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
|
||||
std::string autoFolder = util::generatePathByTID(utinfo->tid) + "/AUTO - " + u->getUsernameSafe() + " - " +
|
||||
util::getDateTime(util::DATE_FMT_YMD) + "/";
|
||||
fs::mkDir(autoFolder.substr(0, autoFolder.length() - 1));
|
||||
fs::copyDirToDirThreaded("sv:/", autoFolder);
|
||||
}
|
||||
|
||||
if(fs::isDir(*restore))
|
||||
if (fs::isDir(*restore))
|
||||
{
|
||||
restore->append("/");
|
||||
if(fs::dirNotEmpty(*restore))
|
||||
if (fs::dirNotEmpty(*restore))
|
||||
{
|
||||
t->status->setStatus(ui::getUICString("threadStatusCalculatingSaveSize", 0));
|
||||
unsigned dirCount = 0, fileCount = 0;
|
||||
uint64_t saveSize = 0;
|
||||
int64_t availSize = 0;
|
||||
int64_t availSize = 0;
|
||||
fs::getDirProps(*restore, dirCount, fileCount, saveSize);
|
||||
fsFsGetTotalSpace(fsdevGetDeviceFileSystem("sv"), "/", &availSize);
|
||||
if((int)saveSize > availSize)
|
||||
if ((int)saveSize > availSize)
|
||||
{
|
||||
data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo();
|
||||
fs::unmountSave();
|
||||
|
|
@ -504,16 +561,16 @@ void fs::restoreBackup(void *a)
|
|||
else
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popFolderIsEmpty", 0));
|
||||
}
|
||||
else if(!fs::isDir(*restore) && util::getExtensionFromString(*restore) == "zip")
|
||||
else if (!fs::isDir(*restore) && util::getExtensionFromString(*restore) == "zip")
|
||||
{
|
||||
unzFile unz = unzOpen64(restore->c_str());
|
||||
if(unz && fs::zipNotEmpty(unz))
|
||||
if (unz && fs::zipNotEmpty(unz))
|
||||
{
|
||||
t->status->setStatus(ui::getUICString("threadStatusCalculatingSaveSize", 0));
|
||||
uint64_t saveSize = fs::getZipTotalSize(unz);
|
||||
int64_t availSize = 0;
|
||||
int64_t availSize = 0;
|
||||
fsFsGetTotalSpace(fsdevGetDeviceFileSystem("sv"), "/", &availSize);
|
||||
if((int)saveSize > availSize)
|
||||
if ((int)saveSize > availSize)
|
||||
{
|
||||
data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo();
|
||||
fs::unmountSave();
|
||||
|
|
@ -536,7 +593,7 @@ void fs::restoreBackup(void *a)
|
|||
fs::copyFileCommitThreaded(*restore, dstPath, "sv");
|
||||
}
|
||||
}
|
||||
if(cfg::config["autoBack"])
|
||||
if (cfg::config["autoBack"])
|
||||
ui::fldRefreshMenu();
|
||||
|
||||
delete restore;
|
||||
|
|
@ -551,7 +608,7 @@ void fs::deleteBackup(void *a)
|
|||
|
||||
t->status->setStatus(ui::getUICString("threadStatusDeletingFile", 0));
|
||||
data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo();
|
||||
if(cfg::config["trashBin"])
|
||||
if (cfg::config["trashBin"])
|
||||
{
|
||||
std::string oldPath = *deletePath;
|
||||
std::string trashPath = wd + "_TRASH_/" + data::getTitleSafeNameByTID(utinfo->tid);
|
||||
|
|
@ -561,7 +618,7 @@ void fs::deleteBackup(void *a)
|
|||
rename(oldPath.c_str(), trashPath.c_str());
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("saveDataBackupMovedToTrash", 0), backupName.c_str());
|
||||
}
|
||||
else if(fs::isDir(*deletePath))
|
||||
else if (fs::isDir(*deletePath))
|
||||
{
|
||||
*deletePath += "/";
|
||||
fs::delDir(*deletePath);
|
||||
|
|
@ -584,23 +641,25 @@ void fs::dumpAllUserSaves(void *a)
|
|||
t->argPtr = c;
|
||||
data::user *u = data::getCurrentUser();
|
||||
|
||||
for(unsigned i = 0; i < u->titleInfo.size(); i++)
|
||||
for (unsigned i = 0; i < u->titleInfo.size(); i++)
|
||||
{
|
||||
bool saveMounted = fs::mountSave(u->titleInfo[i].saveInfo);
|
||||
util::createTitleDirectoryByTID(u->titleInfo[i].tid);
|
||||
if(saveMounted && fs::dirNotEmpty("sv:/") && cfg::config["zip"])
|
||||
if (saveMounted && fs::dirNotEmpty("sv:/") && cfg::config["zip"])
|
||||
{
|
||||
fs::loadPathFilters(u->titleInfo[i].tid);
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
|
||||
util::getDateTime(util::DATE_FMT_YMD) + ".zip";
|
||||
zipFile zip = zipOpen64(dst.c_str(), 0);
|
||||
fs::copyDirToZip("sv:/", zip, false, 0, t);
|
||||
zipClose(zip, NULL);
|
||||
fs::freePathFilters();
|
||||
}
|
||||
else if(saveMounted && fs::dirNotEmpty("sv:/"))
|
||||
else if (saveMounted && fs::dirNotEmpty("sv:/"))
|
||||
{
|
||||
fs::loadPathFilters(u->titleInfo[i].tid);
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
|
||||
util::getDateTime(util::DATE_FMT_YMD) + "/";
|
||||
fs::mkDir(dst.substr(0, dst.length() - 1));
|
||||
fs::copyDirToDir("sv:/", dst, t);
|
||||
fs::freePathFilters();
|
||||
|
|
@ -617,26 +676,28 @@ void fs::dumpAllUsersAllSaves(void *a)
|
|||
fs::copyArgs *c = fs::copyArgsCreate("", "", "", NULL, NULL, false, false, 0);
|
||||
t->argPtr = c;
|
||||
unsigned curUser = 0;
|
||||
while(data::users[curUser].getUID128() != 2)
|
||||
while (data::users[curUser].getUID128() != 2)
|
||||
{
|
||||
data::user *u = &data::users[curUser++];
|
||||
for(unsigned i = 0; i < u->titleInfo.size(); i++)
|
||||
for (unsigned i = 0; i < u->titleInfo.size(); i++)
|
||||
{
|
||||
bool saveMounted = fs::mountSave(u->titleInfo[i].saveInfo);
|
||||
util::createTitleDirectoryByTID(u->titleInfo[i].tid);
|
||||
if(saveMounted && fs::dirNotEmpty("sv:/") && cfg::config["zip"])
|
||||
if (saveMounted && fs::dirNotEmpty("sv:/") && cfg::config["zip"])
|
||||
{
|
||||
fs::loadPathFilters(u->titleInfo[i].tid);
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + ".zip";
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
|
||||
util::getDateTime(util::DATE_FMT_YMD) + ".zip";
|
||||
zipFile zip = zipOpen64(dst.c_str(), 0);
|
||||
fs::copyDirToZip("sv:/", zip, false, 0, t);
|
||||
zipClose(zip, NULL);
|
||||
fs::freePathFilters();
|
||||
}
|
||||
else if(saveMounted && fs::dirNotEmpty("sv:/"))
|
||||
else if (saveMounted && fs::dirNotEmpty("sv:/"))
|
||||
{
|
||||
fs::loadPathFilters(u->titleInfo[i].tid);
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD) + "/";
|
||||
std::string dst = util::generatePathByTID(u->titleInfo[i].tid) + u->getUsernameSafe() + " - " +
|
||||
util::getDateTime(util::DATE_FMT_YMD) + "/";
|
||||
fs::mkDir(dst.substr(0, dst.length() - 1));
|
||||
fs::copyDirToDir("sv:/", dst, t);
|
||||
fs::freePathFilters();
|
||||
|
|
@ -667,4 +728,3 @@ void fs::logWrite(const char *fmt, ...)
|
|||
fsfwrite(tmp, 1, strlen(tmp), debLog);
|
||||
fsfclose(debLog);
|
||||
}
|
||||
|
||||
|
|
|
|||
168
src/ui/fm.cpp
168
src/ui/fm.cpp
|
|
@ -1,11 +1,11 @@
|
|||
#include <string>
|
||||
|
||||
#include "ui.h"
|
||||
#include "file.h"
|
||||
#include "util.h"
|
||||
#include "fm.h"
|
||||
#include "cfg.h"
|
||||
#include "file.h"
|
||||
#include "fm.h"
|
||||
#include "type.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
|
||||
//This is going to be a mess but the old one was too.
|
||||
//It gets more complicated because of system saves and committing.
|
||||
|
|
@ -16,9 +16,9 @@
|
|||
//Struct to hold info so i don't have to if else if if if
|
||||
typedef struct
|
||||
{
|
||||
std::string *path;
|
||||
ui::menu *m;
|
||||
fs::dirList *d;
|
||||
std::string *path;
|
||||
ui::menu *m;
|
||||
fs::dirList *d;
|
||||
} menuFuncArgs;
|
||||
|
||||
static ui::slideOutPanel *devPanel, *sdPanel;
|
||||
|
|
@ -42,7 +42,7 @@ static void refreshMenu(void *a)
|
|||
|
||||
d->reassign(*ma->path);
|
||||
util::copyDirListToMenu(*d, *m);
|
||||
for(int i = 1; i < m->getCount(); i++)
|
||||
for (int i = 1; i < m->getCount(); i++)
|
||||
{
|
||||
m->optAddButtonEvent(i, HidNpadButton_A, _listFunctionA, ma);
|
||||
}
|
||||
|
|
@ -53,10 +53,10 @@ static void refreshMenu(void *a)
|
|||
static void _devMenuCallback(void *a)
|
||||
{
|
||||
menuFuncArgs *ma = (menuFuncArgs *)a;
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
if(*ma->path != dev && *ma->path != "sdmc:/")
|
||||
if (*ma->path != dev && *ma->path != "sdmc:/")
|
||||
{
|
||||
util::removeLastFolderFromString(*ma->path);
|
||||
threadInfo fake;
|
||||
|
|
@ -75,7 +75,7 @@ static void _devMenuCallback(void *a)
|
|||
|
||||
static void _devCopyMenuCallback(void *a)
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
devCopyMenu->setActive(false);
|
||||
|
|
@ -88,10 +88,10 @@ static void _devCopyMenuCallback(void *a)
|
|||
static void _sdMenuCallback(void *a)
|
||||
{
|
||||
menuFuncArgs *ma = (menuFuncArgs *)a;
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
if(*ma->path != dev && *ma->path != "sdmc:/")
|
||||
if (*ma->path != dev && *ma->path != "sdmc:/")
|
||||
{
|
||||
util::removeLastFolderFromString(*ma->path);
|
||||
threadInfo fake;
|
||||
|
|
@ -110,7 +110,7 @@ static void _sdMenuCallback(void *a)
|
|||
|
||||
static void _sdCopyMenuCallback(void *a)
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
sdCopyMenu->setActive(false);
|
||||
|
|
@ -141,13 +141,13 @@ static void _listFunctionA(void *a)
|
|||
|
||||
int sel = m->getSelected();
|
||||
bool isDir = d->isDir(sel - 2);
|
||||
if(sel == 1 && (*ma->path != dev && *ma->path != "sdmc:/"))
|
||||
if (sel == 1 && (*ma->path != dev && *ma->path != "sdmc:/"))
|
||||
{
|
||||
util::removeLastFolderFromString(*ma->path);
|
||||
d->reassign(*ma->path);
|
||||
util::copyDirListToMenu(*d, *m);
|
||||
}
|
||||
else if(sel > 1 && isDir)
|
||||
else if (sel > 1 && isDir)
|
||||
{
|
||||
std::string addToPath = d->getItem(sel - 2);
|
||||
*ma->path += addToPath + "/";
|
||||
|
|
@ -155,7 +155,7 @@ static void _listFunctionA(void *a)
|
|||
util::copyDirListToMenu(*d, *m);
|
||||
}
|
||||
|
||||
for(int i = 1; i < m->getCount(); i++)
|
||||
for (int i = 1; i < m->getCount(); i++)
|
||||
m->optAddButtonEvent(i, HidNpadButton_A, _listFunctionA, ma);
|
||||
}
|
||||
|
||||
|
|
@ -167,49 +167,49 @@ static void _copyMenuCopy_t(void *a)
|
|||
fs::dirList *d = ma->d;
|
||||
|
||||
int sel = m->getSelected();
|
||||
if(ma == devArgs)
|
||||
if (ma == devArgs)
|
||||
{
|
||||
if(sel == 0)
|
||||
if (sel == 0)
|
||||
fs::copyDirToDirThreaded(*ma->path, *sdmcArgs->path);
|
||||
else if(sel > 1 && d->isDir(sel - 2))
|
||||
else if (sel > 1 && d->isDir(sel - 2))
|
||||
{
|
||||
std::string srcPath = *ma->path + d->getItem(sel - 2) + "/";
|
||||
std::string dstPath = *sdmcArgs->path + d->getItem(sel - 2) + "/";
|
||||
mkdir(dstPath.substr(0, dstPath.length() - 1).c_str(), 777);
|
||||
fs::copyDirToDirThreaded(srcPath, dstPath);
|
||||
}
|
||||
else if(sel > 1)
|
||||
else if (sel > 1)
|
||||
{
|
||||
std::string srcPath = *ma->path + d->getItem(sel - 2);
|
||||
std::string dstPath = *sdmcArgs->path + d->getItem(sel - 2);
|
||||
fs::copyFileThreaded(srcPath, dstPath);
|
||||
}
|
||||
}
|
||||
else if(ma == sdmcArgs)
|
||||
else if (ma == sdmcArgs)
|
||||
{
|
||||
//I know
|
||||
if(sel == 0)
|
||||
if (sel == 0)
|
||||
{
|
||||
if(commit)
|
||||
if (commit)
|
||||
fs::copyDirToDirCommitThreaded(*ma->path, *devArgs->path, dev);
|
||||
else
|
||||
fs::copyDirToDirThreaded(*ma->path, *devArgs->path);
|
||||
}
|
||||
else if(sel > 1 && d->isDir(sel - 2))
|
||||
else if (sel > 1 && d->isDir(sel - 2))
|
||||
{
|
||||
std::string srcPath = *ma->path + d->getItem(sel - 2) + "/";
|
||||
std::string dstPath = *devArgs->path + d->getItem(sel - 2) + "/";
|
||||
mkdir(dstPath.substr(0, dstPath.length() - 1).c_str(), 777);
|
||||
if(commit)
|
||||
if (commit)
|
||||
fs::copyDirToDirCommitThreaded(srcPath, dstPath, dev);
|
||||
else
|
||||
fs::copyDirToDirThreaded(srcPath, dstPath);
|
||||
}
|
||||
else if(sel > 1)
|
||||
else if (sel > 1)
|
||||
{
|
||||
std::string srcPath = *ma->path + d->getItem(sel - 2);
|
||||
std::string dstPath = *devArgs->path + d->getItem(sel - 2);
|
||||
if(commit)
|
||||
if (commit)
|
||||
fs::copyFileCommitThreaded(srcPath, dstPath, dev);
|
||||
else
|
||||
fs::copyFileThreaded(srcPath, dstPath);
|
||||
|
|
@ -229,30 +229,36 @@ static void _copyMenuCopy(void *a)
|
|||
|
||||
std::string srcPath, dstPath;
|
||||
int sel = m->getSelected();
|
||||
if(sel == 0 && ma == devArgs)
|
||||
if (sel == 0 && ma == devArgs)
|
||||
{
|
||||
srcPath = *ma->path;
|
||||
dstPath = *sdmcArgs->path;
|
||||
}
|
||||
else if(sel > 1 && ma == devArgs)
|
||||
else if (sel > 1 && ma == devArgs)
|
||||
{
|
||||
srcPath = *ma->path + d->getItem(sel - 2);
|
||||
dstPath = *sdmcArgs->path + d->getItem(sel - 2);
|
||||
}
|
||||
else if(sel == 0 && ma == sdmcArgs)
|
||||
else if (sel == 0 && ma == sdmcArgs)
|
||||
{
|
||||
srcPath = *ma->path;
|
||||
dstPath = *devArgs->path;
|
||||
}
|
||||
else if(sel > 1 && ma == sdmcArgs)
|
||||
else if (sel > 1 && ma == sdmcArgs)
|
||||
{
|
||||
srcPath = *ma->path + d->getItem(m->getSelected() - 2);
|
||||
dstPath = *devArgs->path + d->getItem(m->getSelected() - 2);
|
||||
}
|
||||
|
||||
if(ma == devArgs || (ma == sdmcArgs && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
|
||||
if (ma == devArgs || (ma == sdmcArgs && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
|
||||
{
|
||||
ui::confirmArgs *send = ui::confirmArgsCreate(false, _copyMenuCopy_t, NULL, ma, ui::getUICString("confirmCopy", 0), srcPath.c_str(), dstPath.c_str());
|
||||
ui::confirmArgs *send = ui::confirmArgsCreate(false,
|
||||
_copyMenuCopy_t,
|
||||
NULL,
|
||||
ma,
|
||||
ui::getUICString("confirmCopy", 0),
|
||||
srcPath.c_str(),
|
||||
dstPath.c_str());
|
||||
ui::confirm(send);
|
||||
}
|
||||
}
|
||||
|
|
@ -267,39 +273,39 @@ static void _copyMenuDelete_t(void *a)
|
|||
t->status->setStatus(ui::getUICString("threadStatusDeletingFile", 0));
|
||||
|
||||
int sel = m->getSelected();
|
||||
if(ma == devArgs)
|
||||
if (ma == devArgs)
|
||||
{
|
||||
if(sel == 0 && *ma->path != "sdmc:/")
|
||||
if (sel == 0 && *ma->path != "sdmc:/")
|
||||
{
|
||||
fs::delDir(*ma->path);
|
||||
if(commit)
|
||||
if (commit)
|
||||
fs::commitToDevice(dev);
|
||||
}
|
||||
else if(sel > 1 && d->isDir(sel - 2))
|
||||
else if (sel > 1 && d->isDir(sel - 2))
|
||||
{
|
||||
std::string delPath = *ma->path + d->getItem(sel - 2) + "/";
|
||||
fs::delDir(delPath);
|
||||
if(commit)
|
||||
if (commit)
|
||||
fs::commitToDevice(dev);
|
||||
}
|
||||
else if(sel > 1)
|
||||
else if (sel > 1)
|
||||
{
|
||||
std::string delPath = *ma->path + d->getItem(sel - 2);
|
||||
fs::delfile(delPath);
|
||||
if(commit)
|
||||
if (commit)
|
||||
fs::commitToDevice(dev);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sel == 0 && *ma->path != "sdmc:/")
|
||||
if (sel == 0 && *ma->path != "sdmc:/")
|
||||
fs::delDir(*ma->path);
|
||||
else if(sel > 1 && d->isDir(sel - 2))
|
||||
else if (sel > 1 && d->isDir(sel - 2))
|
||||
{
|
||||
std::string delPath = *ma->path + d->getItem(sel - 2) + "/";
|
||||
fs::delDir(delPath);
|
||||
}
|
||||
else if(sel > 1)
|
||||
else if (sel > 1)
|
||||
{
|
||||
std::string delPath = *ma->path + d->getItem(sel - 2);
|
||||
fs::delfile(delPath);
|
||||
|
|
@ -319,14 +325,20 @@ static void _copyMenuDelete(void *a)
|
|||
|
||||
int sel = m->getSelected();
|
||||
std::string itmPath;
|
||||
if(sel == 0)
|
||||
if (sel == 0)
|
||||
itmPath = *ma->path;
|
||||
else if(sel > 1)
|
||||
else if (sel > 1)
|
||||
itmPath = *ma->path + d->getItem(sel - 2);
|
||||
|
||||
if(ma == sdmcArgs || (ma == devArgs && (sel == 0 || sel > 1) && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
|
||||
if (ma == sdmcArgs ||
|
||||
(ma == devArgs && (sel == 0 || sel > 1) && (type != FsSaveDataType_System || cfg::config["sysSaveWrite"])))
|
||||
{
|
||||
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"], _copyMenuDelete_t, NULL, a, ui::getUICString("confirmDelete", 0), itmPath.c_str());
|
||||
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"],
|
||||
_copyMenuDelete_t,
|
||||
NULL,
|
||||
a,
|
||||
ui::getUICString("confirmDelete", 0),
|
||||
itmPath.c_str());
|
||||
ui::confirm(send);
|
||||
}
|
||||
}
|
||||
|
|
@ -338,13 +350,14 @@ static void _copyMenuRename(void *a)
|
|||
fs::dirList *d = ma->d;
|
||||
|
||||
int sel = m->getSelected();
|
||||
if(sel > 1)
|
||||
if (sel > 1)
|
||||
{
|
||||
std::string getNewName = util::getStringInput(SwkbdType_QWERTY, d->getItem(sel - 2), ui::getUIString("swkbdRename", 0), 64, 0, NULL);
|
||||
if(!getNewName.empty())
|
||||
std::string getNewName =
|
||||
util::getStringInput(SwkbdType_QWERTY, d->getItem(sel - 2), ui::getUIString("swkbdRename", 0), 64, 0, NULL);
|
||||
if (!getNewName.empty())
|
||||
{
|
||||
std::string prevPath = *ma->path + d->getItem(sel - 2);
|
||||
std::string newPath = *ma->path + getNewName;
|
||||
std::string newPath = *ma->path + getNewName;
|
||||
rename(prevPath.c_str(), newPath.c_str());
|
||||
}
|
||||
threadInfo fake;
|
||||
|
|
@ -358,8 +371,13 @@ static void _copyMenuRename(void *a)
|
|||
static void _copyMenuMkDir(void *a)
|
||||
{
|
||||
menuFuncArgs *ma = (menuFuncArgs *)a;
|
||||
std::string getNewFolder = util::getStringInput(SwkbdType_QWERTY, ui::getUIString("fileModeMenuMkDir", 0), ui::getUIString("swkbdMkDir", 0), 64, 0, NULL);
|
||||
if(!getNewFolder.empty())
|
||||
std::string getNewFolder = util::getStringInput(SwkbdType_QWERTY,
|
||||
ui::getUIString("fileModeMenuMkDir", 0),
|
||||
ui::getUIString("swkbdMkDir", 0),
|
||||
64,
|
||||
0,
|
||||
NULL);
|
||||
if (!getNewFolder.empty())
|
||||
{
|
||||
std::string createPath = *ma->path + getNewFolder;
|
||||
mkdir(createPath.c_str(), 777);
|
||||
|
|
@ -379,7 +397,11 @@ static void _copyMenuGetShowDirProps_t(void *a)
|
|||
uint64_t totalSize = 0;
|
||||
t->status->setStatus(ui::getUICString("threadStatusGetDirProps", 0));
|
||||
fs::getDirProps(*p, dirCount, fileCount, totalSize);
|
||||
ui::showMessage(ui::getUICString("fileModeFolderProperties", 0), p->c_str(), dirCount, fileCount, util::getSizeString(totalSize).c_str());
|
||||
ui::showMessage(ui::getUICString("fileModeFolderProperties", 0),
|
||||
p->c_str(),
|
||||
dirCount,
|
||||
fileCount,
|
||||
util::getSizeString(totalSize).c_str());
|
||||
delete p;
|
||||
t->finished = true;
|
||||
}
|
||||
|
|
@ -391,18 +413,18 @@ static void _copyMenuGetProps(void *a)
|
|||
fs::dirList *d = ma->d;
|
||||
|
||||
int sel = m->getSelected();
|
||||
if(sel == 0)
|
||||
if (sel == 0)
|
||||
{
|
||||
std::string *folderPath = new std::string(*ma->path);
|
||||
ui::newThread(_copyMenuGetShowDirProps_t, folderPath, NULL);
|
||||
}
|
||||
else if(sel > 1 && d->isDir(sel - 2))
|
||||
else if (sel > 1 && d->isDir(sel - 2))
|
||||
{
|
||||
std::string *folderPath = new std::string;
|
||||
folderPath->assign(*ma->path + d->getItem(sel - 2) + "/");
|
||||
ui::newThread(_copyMenuGetShowDirProps_t, folderPath, NULL);
|
||||
}
|
||||
else if(sel > 1)
|
||||
else if (sel > 1)
|
||||
{
|
||||
std::string filePath = *ma->path + d->getItem(sel - 2);
|
||||
fs::getShowFileProps(filePath);
|
||||
|
|
@ -412,7 +434,7 @@ static void _copyMenuGetProps(void *a)
|
|||
static void _copyMenuClose(void *a)
|
||||
{
|
||||
menuFuncArgs *ma = (menuFuncArgs *)a;
|
||||
if(ma == devArgs)
|
||||
if (ma == devArgs)
|
||||
{
|
||||
devCopyMenu->setActive(false);
|
||||
devMenu->setActive(true);
|
||||
|
|
@ -433,7 +455,7 @@ static void _devMenuAddToPathFilter(void *a)
|
|||
fs::dirList *d = ma->d;
|
||||
|
||||
int sel = m->getSelected();
|
||||
if(sel > 1)
|
||||
if (sel > 1)
|
||||
{
|
||||
data::userTitleInfo *tinfo = data::getCurrentUserTitleInfo();
|
||||
std::string filterPath = *ma->path + d->getItem(sel - 2);
|
||||
|
|
@ -461,7 +483,7 @@ void ui::fmInit()
|
|||
devCopyMenu->setActive(false);
|
||||
devCopyMenu->setCallback(_devCopyMenuCallback, NULL);
|
||||
devCopyMenu->addOpt(NULL, ui::getUIString("fileModeMenu", 0) + "SDMC");
|
||||
for(int i = 1; i < 4; i++)
|
||||
for (int i = 1; i < 4; i++)
|
||||
devCopyMenu->addOpt(NULL, ui::getUIString("fileModeMenu", i));
|
||||
//Manually do this so I can place the last option higher up
|
||||
devCopyMenu->addOpt(NULL, ui::getUIString("fileModeMenu", 6));
|
||||
|
|
@ -486,7 +508,7 @@ void ui::fmInit()
|
|||
sdCopyMenu = new ui::menu(10, 210, 268, 20, 5);
|
||||
sdCopyMenu->setActive(false);
|
||||
sdCopyMenu->setCallback(_sdCopyMenuCallback, NULL);
|
||||
for(int i = 0; i < 6; i++)
|
||||
for (int i = 0; i < 6; i++)
|
||||
sdCopyMenu->addOpt(NULL, ui::getUIString("fileModeMenu", i));
|
||||
sdCopyMenu->optAddButtonEvent(0, HidNpadButton_A, _copyMenuCopy, sdmcArgs);
|
||||
sdCopyMenu->optAddButtonEvent(1, HidNpadButton_A, _copyMenuDelete, sdmcArgs);
|
||||
|
|
@ -497,7 +519,7 @@ void ui::fmInit()
|
|||
ui::registerPanel(sdPanel);
|
||||
|
||||
devList = new fs::dirList;
|
||||
sdList = new fs::dirList;
|
||||
sdList = new fs::dirList;
|
||||
devArgs->d = devList;
|
||||
sdmcArgs->d = sdList;
|
||||
}
|
||||
|
|
@ -514,10 +536,10 @@ void ui::fmExit()
|
|||
delete sdmcArgs;
|
||||
}
|
||||
|
||||
void ui::fmPrep(const FsSaveDataType& _type, const std::string& _dev, const std::string& _baseSDMC, bool _commit)
|
||||
void ui::fmPrep(FsSaveDataType _type, const std::string &_dev, const std::string &_baseSDMC, bool _commit)
|
||||
{
|
||||
type = _type;
|
||||
dev = _dev;
|
||||
dev = _dev;
|
||||
commit = _commit;
|
||||
devPath = _dev;
|
||||
sdPath = _baseSDMC;
|
||||
|
|
@ -527,24 +549,24 @@ void ui::fmPrep(const FsSaveDataType& _type, const std::string& _dev, const std:
|
|||
devList->reassign(dev);
|
||||
sdList->reassign(sdPath);
|
||||
util::copyDirListToMenu(*devList, *devMenu);
|
||||
for(int i = 1; i < devMenu->getCount(); i++)
|
||||
for (int i = 1; i < devMenu->getCount(); i++)
|
||||
devMenu->optAddButtonEvent(i, HidNpadButton_A, _listFunctionA, devArgs);
|
||||
|
||||
util::copyDirListToMenu(*sdList, *sdMenu);
|
||||
for(int i = 1; i < sdMenu->getCount(); i++)
|
||||
for (int i = 1; i < sdMenu->getCount(); i++)
|
||||
sdMenu->optAddButtonEvent(i, HidNpadButton_A, _listFunctionA, sdmcArgs);
|
||||
}
|
||||
|
||||
void ui::fmUpdate()
|
||||
{
|
||||
//For now? Maybe forever?
|
||||
if(devMenu->getActive() || sdMenu->getActive())
|
||||
if (devMenu->getActive() || sdMenu->getActive())
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_ZL:
|
||||
case HidNpadButton_ZR:
|
||||
if(devMenu->getActive())
|
||||
if (devMenu->getActive())
|
||||
{
|
||||
devMenu->setActive(false);
|
||||
sdMenu->setActive(true);
|
||||
|
|
@ -558,15 +580,15 @@ void ui::fmUpdate()
|
|||
|
||||
case HidNpadButton_Minus:
|
||||
//Can't be 100% sure it's fs's sv
|
||||
if(dev != "sdmc:/")
|
||||
if (dev != "sdmc:/")
|
||||
fsdevUnmountDevice(dev.c_str());
|
||||
|
||||
if(ui::prevState == EX_MNU)
|
||||
if (ui::prevState == EX_MNU)
|
||||
{
|
||||
ui::usrSelPanel->openPanel();
|
||||
ui::changeState(EX_MNU);
|
||||
}
|
||||
else if(ui::prevState == TTL_SEL)
|
||||
else if (ui::prevState == TTL_SEL)
|
||||
{
|
||||
ui::usrSelPanel->openPanel();
|
||||
ui::ttlOptsPanel->openPanel();
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
#include <cmath>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <switch.h>
|
||||
|
||||
#include "gfx.h"
|
||||
#include "ui.h"
|
||||
#include "miscui.h"
|
||||
#include "util.h"
|
||||
#include "type.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
|
||||
static const SDL_Color divLight = {0x6D, 0x6D, 0x6D, 0xFF};
|
||||
static const SDL_Color divDark = {0xCC, 0xCC, 0xCC, 0xFF};
|
||||
static const SDL_Color shadow = {0x66, 0x66, 0x66, 0xFF};
|
||||
static const SDL_Color divLight = {0x6D, 0x6D, 0x6D, 0xFF};
|
||||
static const SDL_Color divDark = {0xCC, 0xCC, 0xCC, 0xFF};
|
||||
static const SDL_Color shadow = {0x66, 0x66, 0x66, 0xFF};
|
||||
|
||||
static const SDL_Color fillBack = {0x66, 0x66, 0x66, 0xFF};
|
||||
static const SDL_Color fillBar = {0x00, 0xDD, 0x00, 0xFF};
|
||||
static const SDL_Color fillBack = {0x66, 0x66, 0x66, 0xFF};
|
||||
static const SDL_Color fillBar = {0x00, 0xDD, 0x00, 0xFF};
|
||||
|
||||
static const SDL_Color menuColorLight = {0x32, 0x50, 0xF0, 0xFF};
|
||||
static const SDL_Color menuColorDark = {0x00, 0xFF, 0xC5, 0xFF};
|
||||
static const SDL_Color menuColorDark = {0x00, 0xFF, 0xC5, 0xFF};
|
||||
|
||||
ui::menu::menu(const int& _x, const int& _y, const int& _rW, const int& _fS, const int& _mL)
|
||||
ui::menu::menu(int _x, int _y, int _rW, int _fS, int _mL)
|
||||
{
|
||||
x = _x;
|
||||
mY = _y;
|
||||
|
|
@ -37,7 +37,7 @@ ui::menu::menu(const int& _x, const int& _y, const int& _rW, const int& _fS, con
|
|||
|
||||
void ui::menu::editParam(int _param, int newVal)
|
||||
{
|
||||
switch(_param)
|
||||
switch (_param)
|
||||
{
|
||||
case MENU_X:
|
||||
x = newVal;
|
||||
|
|
@ -50,14 +50,22 @@ void ui::menu::editParam(int _param, int newVal)
|
|||
case MENU_RECT_WIDTH:
|
||||
rW = newVal;
|
||||
SDL_DestroyTexture(optTex);
|
||||
optTex = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, rW, rH);
|
||||
optTex = SDL_CreateTexture(gfx::render,
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET,
|
||||
rW,
|
||||
rH);
|
||||
SDL_SetTextureBlendMode(optTex, SDL_BLENDMODE_BLEND);
|
||||
break;
|
||||
|
||||
case MENU_RECT_HEIGHT:
|
||||
rH = newVal;
|
||||
SDL_DestroyTexture(optTex);
|
||||
optTex = SDL_CreateTexture(gfx::render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET, rW, rH);
|
||||
optTex = SDL_CreateTexture(gfx::render,
|
||||
SDL_PIXELFORMAT_RGBA8888,
|
||||
SDL_TEXTUREACCESS_STATIC | SDL_TEXTUREACCESS_TARGET,
|
||||
rW,
|
||||
rH);
|
||||
SDL_SetTextureBlendMode(optTex, SDL_BLENDMODE_BLEND);
|
||||
break;
|
||||
|
||||
|
|
@ -71,7 +79,7 @@ void ui::menu::editParam(int _param, int newVal)
|
|||
}
|
||||
}
|
||||
|
||||
int ui::menu::addOpt(SDL_Texture *_icn, const std::string& add)
|
||||
int ui::menu::addOpt(SDL_Texture *_icn, const std::string &add)
|
||||
{
|
||||
ui::menuOpt newOpt;
|
||||
newOpt.txt = add;
|
||||
|
|
@ -81,9 +89,9 @@ int ui::menu::addOpt(SDL_Texture *_icn, const std::string& add)
|
|||
return opt.size() - 1;
|
||||
}
|
||||
|
||||
void ui::menu::editOpt(int ind, SDL_Texture *_icn, const std::string& ch)
|
||||
void ui::menu::editOpt(int ind, SDL_Texture *_icn, const std::string &ch)
|
||||
{
|
||||
if(!opt[ind].icn && _icn)
|
||||
if (!opt[ind].icn && _icn)
|
||||
opt[ind].icn = _icn;
|
||||
|
||||
opt[ind].txt = ch;
|
||||
|
|
@ -96,11 +104,11 @@ void ui::menu::optAddButtonEvent(unsigned _ind, HidNpadButton _button, funcPtr _
|
|||
opt[_ind].events.push_back(newEvent);
|
||||
}
|
||||
|
||||
int ui::menu::getOptPos(const std::string& txt)
|
||||
int ui::menu::getOptPos(const std::string &txt)
|
||||
{
|
||||
for(unsigned i = 0; i < opt.size(); i++)
|
||||
for (unsigned i = 0; i < opt.size(); i++)
|
||||
{
|
||||
if(opt[i].txt == txt)
|
||||
if (opt[i].txt == txt)
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -114,49 +122,49 @@ ui::menu::~menu()
|
|||
|
||||
void ui::menu::update()
|
||||
{
|
||||
if(!isActive)
|
||||
if (!isActive)
|
||||
return;
|
||||
|
||||
uint64_t down = ui::padKeysDown();
|
||||
uint64_t held = ui::padKeysHeld();
|
||||
|
||||
if(held & HidNpadButton_AnyUp || held & HidNpadButton_AnyDown)
|
||||
if (held & HidNpadButton_AnyUp || held & HidNpadButton_AnyDown)
|
||||
++fc;
|
||||
else
|
||||
fc = 0;
|
||||
|
||||
if(fc > 10)
|
||||
if (fc > 10)
|
||||
fc = 0;
|
||||
|
||||
int oldSel = selected;
|
||||
int mSize = opt.size() - 1;
|
||||
bool change = false;
|
||||
if( (down & HidNpadButton_AnyUp) || ((held & HidNpadButton_AnyUp) && fc == 10) )
|
||||
if ((down & HidNpadButton_AnyUp) || ((held & HidNpadButton_AnyUp) && fc == 10))
|
||||
{
|
||||
if(--selected < 0)
|
||||
if (--selected < 0)
|
||||
selected = mSize;
|
||||
|
||||
change = true;
|
||||
}
|
||||
else if( (down & HidNpadButton_AnyDown) || ((held & HidNpadButton_AnyDown) && fc == 10))
|
||||
else if ((down & HidNpadButton_AnyDown) || ((held & HidNpadButton_AnyDown) && fc == 10))
|
||||
{
|
||||
if(++selected > mSize)
|
||||
if (++selected > mSize)
|
||||
selected = 0;
|
||||
|
||||
change = true;
|
||||
}
|
||||
else if(down & HidNpadButton_AnyLeft)
|
||||
else if (down & HidNpadButton_AnyLeft)
|
||||
{
|
||||
selected -= mL;
|
||||
if(selected < 0)
|
||||
if (selected < 0)
|
||||
selected = 0;
|
||||
|
||||
change = true;
|
||||
}
|
||||
else if(down & HidNpadButton_AnyRight)
|
||||
else if (down & HidNpadButton_AnyRight)
|
||||
{
|
||||
selected += mL;
|
||||
if(selected > mSize)
|
||||
if (selected > mSize)
|
||||
selected = mSize;
|
||||
|
||||
change = true;
|
||||
|
|
@ -164,120 +172,145 @@ void ui::menu::update()
|
|||
|
||||
++hoverCount;
|
||||
|
||||
if(!change && hoverCount >= 90)
|
||||
if (!change && hoverCount >= 90)
|
||||
hover = true;
|
||||
else if(change)
|
||||
else if (change)
|
||||
{
|
||||
hoverCount = 0;
|
||||
hover = false;
|
||||
}
|
||||
|
||||
if(down && !opt[selected].events.empty())
|
||||
if (down && !opt[selected].events.empty())
|
||||
{
|
||||
for(ui::menuOptEvent& e : opt[selected].events)
|
||||
for (ui::menuOptEvent &e : opt[selected].events)
|
||||
{
|
||||
if((down & e.button) && e.func)
|
||||
if ((down & e.button) && e.func)
|
||||
(*e.func)(e.args);
|
||||
}
|
||||
}
|
||||
|
||||
if(selected <= mL)
|
||||
if (selected <= mL)
|
||||
tY = mY;
|
||||
else if(selected >= (mSize - mL) && mSize > mL * 2)
|
||||
else if (selected >= (mSize - mL) && mSize > mL * 2)
|
||||
tY = mY + -(rH * (mSize - (mL * 2)));
|
||||
else if(selected > mL && selected < (mSize - mL))
|
||||
else if (selected > mL && selected < (mSize - mL))
|
||||
tY = -(rH * (selected - mL));
|
||||
|
||||
if(selected != oldSel && onChange)
|
||||
if (selected != oldSel && onChange)
|
||||
(*onChange)(NULL);
|
||||
|
||||
if(callback)
|
||||
if (callback)
|
||||
(*callback)(callbackArgs);
|
||||
}
|
||||
|
||||
void ui::menu::draw(SDL_Texture *target, const SDL_Color *textClr, bool drawText)
|
||||
{
|
||||
if(opt.size() < 1)
|
||||
if (opt.size() < 1)
|
||||
return;
|
||||
|
||||
int tH = 0;
|
||||
SDL_QueryTexture(target, NULL, NULL, NULL, &tH);
|
||||
|
||||
if(y != tY)
|
||||
if (y != tY)
|
||||
{
|
||||
float add = (float)((float)tY - (float)y) / ui::animScale;
|
||||
y += ceil(add);
|
||||
}
|
||||
|
||||
if(clrAdd)
|
||||
if (clrAdd)
|
||||
{
|
||||
clrSh += 6;
|
||||
if(clrSh >= 0x72)
|
||||
if (clrSh >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrSh -= 3;
|
||||
if(clrSh <= 0x00)
|
||||
if (clrSh <= 0x00)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
for(int i = 0, tY = y; i < (int)opt.size(); i++, tY += rH)
|
||||
for (int i = 0, tY = y; i < (int)opt.size(); i++, tY += rH)
|
||||
{
|
||||
if(tY < -rH || tY > tH)
|
||||
if (tY < -rH || tY > tH)
|
||||
continue;
|
||||
|
||||
gfx::clearTarget(optTex, &ui::transparent);
|
||||
|
||||
//Todo: Clean this up maybe
|
||||
if(i == selected && drawText)
|
||||
if (i == selected && drawText)
|
||||
{
|
||||
if(isActive)
|
||||
if (isActive)
|
||||
ui::drawBoundBox(target, x, y + (i * rH), rW, rH, clrSh);
|
||||
|
||||
gfx::drawRect(target, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, x + 10, ((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2, 4, fSize + 4);
|
||||
gfx::drawRect(target,
|
||||
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
|
||||
x + 10,
|
||||
((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2,
|
||||
4,
|
||||
fSize + 4);
|
||||
|
||||
static int dX = 0;
|
||||
if(hover && opt[i].txtWidth > rW - 24)
|
||||
if (hover && opt[i].txtWidth > rW - 24)
|
||||
{
|
||||
if((dX -= 2) <= -(opt[i].txtWidth + spcWidth))
|
||||
if ((dX -= 2) <= -(opt[i].txtWidth + spcWidth))
|
||||
{
|
||||
dX = 0;
|
||||
hoverCount = 0;
|
||||
hover = false;
|
||||
}
|
||||
|
||||
gfx::drawTextf(optTex, fSize, dX, ((rH - 8) / 2) - fSize / 2, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].txt.c_str());
|
||||
gfx::drawTextf(optTex, fSize, dX + opt[i].txtWidth + spcWidth, ((rH - 8) / 2) - fSize / 2, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].txt.c_str());
|
||||
gfx::drawTextf(optTex,
|
||||
fSize,
|
||||
dX,
|
||||
((rH - 8) / 2) - fSize / 2,
|
||||
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
|
||||
opt[i].txt.c_str());
|
||||
gfx::drawTextf(optTex,
|
||||
fSize,
|
||||
dX + opt[i].txtWidth + spcWidth,
|
||||
((rH - 8) / 2) - fSize / 2,
|
||||
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
|
||||
opt[i].txt.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
dX = 0;
|
||||
gfx::drawTextf(optTex, fSize, 0, ((rH - 8) / 2) - fSize / 2, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, opt[i].txt.c_str());
|
||||
gfx::drawTextf(optTex,
|
||||
fSize,
|
||||
0,
|
||||
((rH - 8) / 2) - fSize / 2,
|
||||
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
|
||||
opt[i].txt.c_str());
|
||||
}
|
||||
gfx::texDraw(target, optTex, x + 20, (y + 4 + (i * rH)));
|
||||
}
|
||||
else if(i == selected && !drawText && opt[i].icn)
|
||||
else if (i == selected && !drawText && opt[i].icn)
|
||||
{
|
||||
int w, h;
|
||||
SDL_QueryTexture(opt[i].icn, NULL, NULL, &w, &h);
|
||||
float scale = (float)fSize / (float)h;
|
||||
int dW = scale * w;
|
||||
int dH = scale * h;
|
||||
if(isActive)
|
||||
if (isActive)
|
||||
ui::drawBoundBox(target, x, y + (i * rH), rW, rH, clrSh);
|
||||
|
||||
gfx::drawRect(target, ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark, x + 10, ((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2, 4, fSize + 4);
|
||||
gfx::drawRect(target,
|
||||
ui::thmID == ColorSetId_Light ? &menuColorLight : &menuColorDark,
|
||||
x + 10,
|
||||
((y + (rH / 2 - fSize / 2)) + (i * rH)) - 2,
|
||||
4,
|
||||
fSize + 4);
|
||||
gfx::texDrawStretch(optTex, opt[i].icn, 0, ((rH - 8) / 2) - fSize / 2, dW, dH);
|
||||
gfx::texDraw(target, optTex, x + 20, (y + 4 + (i * rH)));
|
||||
}
|
||||
else if(drawText)
|
||||
else if (drawText)
|
||||
{
|
||||
gfx::clearTarget(optTex, &ui::transparent);
|
||||
gfx::drawTextf(optTex, fSize, 0, ((rH - 8) / 2) - fSize / 2, textClr, opt[i].txt.c_str());
|
||||
gfx::texDraw(target, optTex, x + 20, (y + 4 + (i * rH)));
|
||||
}
|
||||
else if(!drawText && opt[i].icn)
|
||||
else if (!drawText && opt[i].icn)
|
||||
{
|
||||
int w, h;
|
||||
SDL_QueryTexture(opt[i].icn, NULL, NULL, &w, &h);
|
||||
|
|
@ -304,15 +337,15 @@ void ui::menu::setActive(bool _set)
|
|||
isActive = _set;
|
||||
}
|
||||
|
||||
void ui::progBar::update(const uint64_t& _prog)
|
||||
void ui::progBar::update(uint64_t _prog)
|
||||
{
|
||||
prog = _prog;
|
||||
|
||||
if(max > 0)
|
||||
if (max > 0)
|
||||
width = (float)((float)prog / (float)max) * 648.0f;
|
||||
}
|
||||
|
||||
void ui::progBar::draw(const std::string& text)
|
||||
void ui::progBar::draw(const std::string &text)
|
||||
{
|
||||
char progStr[64];
|
||||
sprintf(progStr, "%.2fMB / %.2fMB", (float)prog / 1024.0f / 1024.0f, (float)max / 1024.0f / 1024.0f);
|
||||
|
|
@ -334,29 +367,29 @@ ui::popMessageMngr::~popMessageMngr()
|
|||
void ui::popMessageMngr::update()
|
||||
{
|
||||
//Anything that needs graphics/text must be processed on main thread
|
||||
for(ui::popMessage& p : popQueue)
|
||||
for (ui::popMessage &p : popQueue)
|
||||
{
|
||||
p.rectWidth = gfx::getTextWidth(p.message.c_str(), 24) + 32;
|
||||
message.push_back(p);
|
||||
}
|
||||
popQueue.clear();
|
||||
|
||||
for(unsigned i = 0; i < message.size(); i++)
|
||||
for (unsigned i = 0; i < message.size(); i++)
|
||||
{
|
||||
message[i].frames--;
|
||||
if(message[i].frames <= 0)
|
||||
if (message[i].frames <= 0)
|
||||
message.erase(message.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
void ui::popMessageMngr::popMessageAdd(const std::string& mess, int frameTime)
|
||||
void ui::popMessageMngr::popMessageAdd(const std::string &mess, int frameTime)
|
||||
{
|
||||
//Suppress multiple of the same
|
||||
int lastMessageIndex = message.size() - 1;
|
||||
std::string lastMessage;
|
||||
if(lastMessageIndex >= 0)
|
||||
if (lastMessageIndex >= 0)
|
||||
lastMessage = message[lastMessageIndex].message;
|
||||
if(lastMessage != mess)
|
||||
if (lastMessage != mess)
|
||||
{
|
||||
ui::popMessage newPop = {mess, 0, frameTime};
|
||||
popQueue.push_back(newPop);
|
||||
|
|
@ -366,10 +399,10 @@ void ui::popMessageMngr::popMessageAdd(const std::string& mess, int frameTime)
|
|||
void ui::popMessageMngr::draw()
|
||||
{
|
||||
int y = 640;
|
||||
for(auto& p : message)
|
||||
for (auto &p : message)
|
||||
{
|
||||
y -= 48;
|
||||
if(p.y != y)
|
||||
if (p.y != y)
|
||||
p.y += (y - p.y) / ui::animScale;
|
||||
|
||||
gfx::drawRect(NULL, &ui::tboxClr, 64, p.y, p.rectWidth, 40);
|
||||
|
|
@ -377,7 +410,12 @@ void ui::popMessageMngr::draw()
|
|||
}
|
||||
}
|
||||
|
||||
ui::confirmArgs *ui::confirmArgsCreate(bool _hold, funcPtr _confFunc, funcPtr _cancelFunc, void *_funcArgs, const char *fmt, ...)
|
||||
ui::confirmArgs *ui::confirmArgsCreate(bool _hold,
|
||||
funcPtr _confFunc,
|
||||
funcPtr _cancelFunc,
|
||||
void *_funcArgs,
|
||||
const char *fmt,
|
||||
...)
|
||||
{
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
|
|
@ -401,35 +439,35 @@ void confirm_t(void *a)
|
|||
threadInfo *t = (threadInfo *)a;
|
||||
ui::confirmArgs *c = (ui::confirmArgs *)t->argPtr;
|
||||
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
uint64_t down = ui::padKeysDown();
|
||||
uint64_t held = ui::padKeysHeld();
|
||||
|
||||
if((down & HidNpadButton_A) && !c->hold)
|
||||
if ((down & HidNpadButton_A) && !c->hold)
|
||||
{
|
||||
ui::newThread(c->confFunc, c->args, NULL);
|
||||
break;
|
||||
}
|
||||
else if((held & HidNpadButton_A) && c->hold)
|
||||
else if ((held & HidNpadButton_A) && c->hold)
|
||||
{
|
||||
if(c->frameCount % 4 == 0 && ++c->lgFrame > 7)
|
||||
if (c->frameCount % 4 == 0 && ++c->lgFrame > 7)
|
||||
c->lgFrame = 0;
|
||||
|
||||
if(c->frameCount >= 120)
|
||||
if (c->frameCount >= 120)
|
||||
{
|
||||
ui::newThread(c->confFunc, c->args, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(down & HidNpadButton_B)
|
||||
else if (down & HidNpadButton_B)
|
||||
{
|
||||
if(c->cancelFunc)
|
||||
if (c->cancelFunc)
|
||||
(*c->cancelFunc)(c->args);
|
||||
break;
|
||||
}
|
||||
|
||||
svcSleepThread(1e+9 / 60);//Close enough
|
||||
svcSleepThread(1e+9 / 60); //Close enough
|
||||
}
|
||||
delete c;
|
||||
t->finished = true;
|
||||
|
|
@ -440,19 +478,19 @@ void confirmDrawFunc(void *a)
|
|||
{
|
||||
threadInfo *t = (threadInfo *)a;
|
||||
ui::confirmArgs *c = (ui::confirmArgs *)t->argPtr;
|
||||
if(!t->finished)
|
||||
if (!t->finished)
|
||||
{
|
||||
std::string yesTxt = ui::getUIString("dialogYes", 0);
|
||||
unsigned yesX = 0;
|
||||
|
||||
if((ui::padKeysHeld() & HidNpadButton_A) && c->hold)
|
||||
if ((ui::padKeysHeld() & HidNpadButton_A) && c->hold)
|
||||
{
|
||||
c->frameCount++;
|
||||
if(c->frameCount <= 40)
|
||||
if (c->frameCount <= 40)
|
||||
yesTxt = ui::getUIString("holdingText", 0);
|
||||
else if(c->frameCount <= 80)
|
||||
else if (c->frameCount <= 80)
|
||||
yesTxt = ui::getUIString("holdingText", 1);
|
||||
else if(c->frameCount <= 120)
|
||||
else if (c->frameCount <= 120)
|
||||
yesTxt = ui::getUICString("holdingText", 2);
|
||||
|
||||
yesTxt += ui::loadGlyphArray[c->lgFrame];
|
||||
|
|
@ -481,9 +519,9 @@ static void showMessage_t(void *a)
|
|||
{
|
||||
threadInfo *t = (threadInfo *)a;
|
||||
std::string *text = (std::string *)t->argPtr;
|
||||
while(true)
|
||||
while (true)
|
||||
{
|
||||
if(ui::padKeysDown() & HidNpadButton_A)
|
||||
if (ui::padKeysDown() & HidNpadButton_A)
|
||||
break;
|
||||
|
||||
svcSleepThread(1e+9 / 60);
|
||||
|
|
@ -496,7 +534,7 @@ static void showMessageDrawFunc(void *a)
|
|||
{
|
||||
threadInfo *t = (threadInfo *)a;
|
||||
std::string *text = (std::string *)t->argPtr;
|
||||
if(!t->finished)
|
||||
if (!t->finished)
|
||||
{
|
||||
unsigned okX = 640 - (gfx::getTextWidth(ui::getUICString("dialogOK", 0), 18) / 2);
|
||||
ui::drawTextbox(NULL, 280, 262, 720, 256);
|
||||
|
|
@ -526,7 +564,7 @@ void ui::drawTextbox(SDL_Texture *target, int x, int y, int w, int h)
|
|||
gfx::texDraw(target, ui::cornerTopRight, (x + w) - 32, y);
|
||||
|
||||
//middle
|
||||
gfx::drawRect(target, &ui::tboxClr, x, y + 32, w, h - 64);
|
||||
gfx::drawRect(target, &ui::tboxClr, x, y + 32, w, h - 64);
|
||||
|
||||
//bottom
|
||||
gfx::texDraw(target, ui::cornerBottomLeft, x, (y + h) - 32);
|
||||
|
|
@ -539,7 +577,7 @@ void ui::drawBoundBox(SDL_Texture *target, int x, int y, int w, int h, uint8_t c
|
|||
SDL_SetRenderTarget(gfx::render, target);
|
||||
SDL_Color rectClr;
|
||||
|
||||
if(ui::thmID == ColorSetId_Light)
|
||||
if (ui::thmID == ColorSetId_Light)
|
||||
rectClr = {0xFD, 0xFD, 0xFD, 0xFF};
|
||||
else
|
||||
rectClr = {0x21, 0x22, 0x21, 0xFF};
|
||||
|
|
|
|||
206
src/ui/ttl.cpp
206
src/ui/ttl.cpp
|
|
@ -1,10 +1,10 @@
|
|||
#include <vector>
|
||||
|
||||
#include "ui.h"
|
||||
#include "ttl.h"
|
||||
#include "file.h"
|
||||
#include "util.h"
|
||||
#include "cfg.h"
|
||||
#include "file.h"
|
||||
#include "ttl.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
|
||||
static int ttlHelpX = 0;
|
||||
static std::vector<ui::titleview *> ttlViews;
|
||||
|
|
@ -16,7 +16,7 @@ static Mutex ttlViewLock = 0;
|
|||
void ui::ttlRefresh()
|
||||
{
|
||||
mutexLock(&ttlViewLock);
|
||||
for(int i = 0; i < (int)data::users.size(); i++)
|
||||
for (int i = 0; i < (int)data::users.size(); i++)
|
||||
ttlViews[i]->refresh();
|
||||
mutexUnlock(&ttlViewLock);
|
||||
}
|
||||
|
|
@ -29,12 +29,12 @@ static void ttlViewCallback(void *a)
|
|||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
uint64_t tid = d->tid;
|
||||
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_A:
|
||||
if(fs::mountSave(d->saveInfo))
|
||||
if (fs::mountSave(d->saveInfo))
|
||||
{
|
||||
ttlViews[curUserIndex]->setActive(false, true);
|
||||
ttlViews[curUserIndex]->setActive(false, true);
|
||||
ui::fldPopulateMenu();
|
||||
}
|
||||
break;
|
||||
|
|
@ -52,28 +52,28 @@ static void ttlViewCallback(void *a)
|
|||
break;
|
||||
|
||||
case HidNpadButton_Y:
|
||||
{
|
||||
cfg::addTitleToFavorites(tid);
|
||||
int newSel = data::getTitleIndexInUser(data::users[curUserIndex], tid);
|
||||
ttlViews[curUserIndex]->setSelected(newSel);
|
||||
}
|
||||
break;
|
||||
{
|
||||
cfg::addTitleToFavorites(tid);
|
||||
int newSel = data::getTitleIndexInUser(data::users[curUserIndex], tid);
|
||||
ttlViews[curUserIndex]->setSelected(newSel);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ttlOptsCallback(void *a)
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
{
|
||||
int curUserIndex = data::getCurrentUserIndex();
|
||||
ttlOpts->setActive(false);
|
||||
ui::ttlOptsPanel->closePanel();
|
||||
ttlViews[curUserIndex]->setActive(true, true);
|
||||
ui::updateInput();
|
||||
}
|
||||
break;
|
||||
{
|
||||
int curUserIndex = data::getCurrentUserIndex();
|
||||
ttlOpts->setActive(false);
|
||||
ui::ttlOptsPanel->closePanel();
|
||||
ttlViews[curUserIndex]->setActive(true, true);
|
||||
ui::updateInput();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,14 +86,14 @@ static void ttlOptsPanelDraw(void *a)
|
|||
static void ttlOptsShowInfoPanel(void *)
|
||||
{
|
||||
data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo();
|
||||
data::titleInfo *tinfo = data::getTitleInfoByTID(utinfo->tid);
|
||||
data::titleInfo *tinfo = data::getTitleInfoByTID(utinfo->tid);
|
||||
|
||||
char tmp[256];
|
||||
sprintf(tmp, ui::getUICString("infoStatus", 4), tinfo->author.c_str());
|
||||
|
||||
size_t titleWidth = gfx::getTextWidth(tinfo->title.c_str(), 18);
|
||||
size_t pubWidth = gfx::getTextWidth(tmp, 18);
|
||||
if(titleWidth > 410 || pubWidth > 410)
|
||||
if (titleWidth > 410 || pubWidth > 410)
|
||||
{
|
||||
size_t newWidth = titleWidth > pubWidth ? titleWidth : pubWidth;
|
||||
infoPanel->resizePanel(newWidth + 40, 720, 0);
|
||||
|
|
@ -109,7 +109,12 @@ static void ttlOptsShowInfoPanel(void *)
|
|||
static void ttlOptsBlacklistTitle(void *a)
|
||||
{
|
||||
std::string title = data::getTitleNameByTID(data::getCurrentUserTitleInfo()->tid);
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(false, cfg::addTitleToBlacklist, NULL, NULL, ui::getUICString("confirmBlacklist", 0), title.c_str());
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(false,
|
||||
cfg::addTitleToBlacklist,
|
||||
NULL,
|
||||
NULL,
|
||||
ui::getUICString("confirmBlacklist", 0),
|
||||
title.c_str());
|
||||
ui::confirm(conf);
|
||||
}
|
||||
|
||||
|
|
@ -117,15 +122,16 @@ static void ttlOptsDefinePath(void *a)
|
|||
{
|
||||
uint64_t tid = data::getCurrentUserTitleInfo()->tid;
|
||||
std::string safeTitle = data::getTitleInfoByTID(tid)->safeTitle;
|
||||
std::string newSafeTitle = util::getStringInput(SwkbdType_QWERTY, safeTitle, ui::getUICString("swkbdNewSafeTitle", 0), 0x200, 0, NULL);
|
||||
if(!newSafeTitle.empty())
|
||||
std::string newSafeTitle =
|
||||
util::getStringInput(SwkbdType_QWERTY, safeTitle, ui::getUICString("swkbdNewSafeTitle", 0), 0x200, 0, NULL);
|
||||
if (!newSafeTitle.empty())
|
||||
cfg::pathDefAdd(tid, newSafeTitle);
|
||||
}
|
||||
|
||||
static void ttlOptsToFileMode(void *a)
|
||||
{
|
||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
if(fs::mountSave(d->saveInfo))
|
||||
if (fs::mountSave(d->saveInfo))
|
||||
{
|
||||
data::userTitleInfo *utinfo = data::getCurrentUserTitleInfo();
|
||||
std::string sdmcPath = util::generatePathByTID(utinfo->tid);
|
||||
|
|
@ -143,10 +149,10 @@ static void ttlOptsDeleteAllBackups_t(void *a)
|
|||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
std::string targetPath = util::generatePathByTID(d->tid);
|
||||
fs::dirList *backupList = new fs::dirList(targetPath);
|
||||
for(unsigned i = 0; i < backupList->getCount(); i++)
|
||||
for (unsigned i = 0; i < backupList->getCount(); i++)
|
||||
{
|
||||
std::string delPath = targetPath + backupList->getItem(i);
|
||||
if(backupList->isDir(i))
|
||||
if (backupList->isDir(i))
|
||||
{
|
||||
delPath += "/";
|
||||
fs::delDir(delPath);
|
||||
|
|
@ -163,7 +169,12 @@ static void ttlOptsDeleteAllBackups(void *a)
|
|||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
std::string currentTitle = data::getTitleNameByTID(d->tid);
|
||||
|
||||
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteAllBackups_t, NULL, NULL, ui::getUICString("confirmDeleteBackupsTitle", 0), currentTitle.c_str());
|
||||
ui::confirmArgs *send = ui::confirmArgsCreate(cfg::config["holdDel"],
|
||||
ttlOptsDeleteAllBackups_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ui::getUICString("confirmDeleteBackupsTitle", 0),
|
||||
currentTitle.c_str());
|
||||
ui::confirm(send);
|
||||
}
|
||||
|
||||
|
|
@ -185,10 +196,15 @@ static void ttlOptsResetSaveData_t(void *a)
|
|||
static void ttlOptsResetSaveData(void *a)
|
||||
{
|
||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
if(d->saveInfo.save_data_type != FsSaveDataType_System)
|
||||
if (d->saveInfo.save_data_type != FsSaveDataType_System)
|
||||
{
|
||||
std::string title = data::getTitleNameByTID(d->tid);
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsResetSaveData_t, NULL, NULL, ui::getUICString("confirmResetSaveData", 0), title.c_str());
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"],
|
||||
ttlOptsResetSaveData_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ui::getUICString("confirmResetSaveData", 0),
|
||||
title.c_str());
|
||||
ui::confirm(conf);
|
||||
}
|
||||
}
|
||||
|
|
@ -202,13 +218,14 @@ static void ttlOptsDeleteSaveData_t(void *a)
|
|||
|
||||
std::string title = data::getTitleNameByTID(d->tid);
|
||||
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), title.c_str());
|
||||
if(R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)d->saveInfo.save_data_space_id, d->saveInfo.save_data_id)))
|
||||
if (R_SUCCEEDED(fsDeleteSaveDataFileSystemBySaveDataSpaceId((FsSaveDataSpaceId)d->saveInfo.save_data_space_id,
|
||||
d->saveInfo.save_data_id)))
|
||||
{
|
||||
data::loadUsersTitles(false);
|
||||
if(u->titleInfo.size() == 0)
|
||||
if (u->titleInfo.size() == 0)
|
||||
{
|
||||
//Kick back to user
|
||||
ui::ttlOptsPanel->closePanel();//JIC
|
||||
ui::ttlOptsPanel->closePanel(); //JIC
|
||||
ttlOpts->setActive(false);
|
||||
ttlViews[userIndex]->setActive(false, false);
|
||||
ui::usrMenu->setActive(true);
|
||||
|
|
@ -223,10 +240,15 @@ static void ttlOptsDeleteSaveData_t(void *a)
|
|||
static void ttlOptsDeleteSaveData(void *a)
|
||||
{
|
||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
if(d->saveInfo.save_data_type != FsSaveDataType_System)
|
||||
if (d->saveInfo.save_data_type != FsSaveDataType_System)
|
||||
{
|
||||
std::string title = data::getTitleNameByTID(d->tid);
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"], ttlOptsDeleteSaveData_t, NULL, NULL, ui::getUICString("confirmDeleteSaveData", 0), title.c_str());
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(cfg::config["holdDel"],
|
||||
ttlOptsDeleteSaveData_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ui::getUICString("confirmDeleteSaveData", 0),
|
||||
title.c_str());
|
||||
ui::confirm(conf);
|
||||
}
|
||||
}
|
||||
|
|
@ -234,9 +256,10 @@ static void ttlOptsDeleteSaveData(void *a)
|
|||
static void ttlOptsExtendSaveData(void *a)
|
||||
{
|
||||
data::userTitleInfo *d = data::getCurrentUserTitleInfo();
|
||||
if(d->saveInfo.save_data_type != FsSaveDataType_System)
|
||||
if (d->saveInfo.save_data_type != FsSaveDataType_System)
|
||||
{
|
||||
std::string expSizeStr = util::getStringInput(SwkbdType_NumPad, "", ui::getUICString("swkbdExpandSize", 0), 4, 0, NULL);
|
||||
std::string expSizeStr =
|
||||
util::getStringInput(SwkbdType_NumPad, "", ui::getUICString("swkbdExpandSize", 0), 4, 0, NULL);
|
||||
uint64_t extMB = strtoul(expSizeStr.c_str(), NULL, 10) * 0x100000;
|
||||
fs::extendSaveDataThreaded(d, extMB);
|
||||
}
|
||||
|
|
@ -244,27 +267,36 @@ static void ttlOptsExtendSaveData(void *a)
|
|||
|
||||
static void ttlOptsExportSVI(void *a)
|
||||
{
|
||||
data::userTitleInfo *ut = data::getCurrentUserTitleInfo();
|
||||
data::titleInfo *t = data::getTitleInfoByTID(ut->tid);
|
||||
std::string out = fs::getWorkDir() + "svi/";
|
||||
fs::mkDir(out.substr(0, out.length() - 1));
|
||||
out += util::getIDStr(ut->tid) + ".svi";
|
||||
FILE *svi = fopen(out.c_str(), "wb");
|
||||
if(svi)
|
||||
{
|
||||
//Grab icon
|
||||
NsApplicationControlData *ctrlData = new NsApplicationControlData;
|
||||
uint64_t ctrlSize = 0;
|
||||
nsGetApplicationControlData(NsApplicationControlSource_Storage, ut->tid, ctrlData, sizeof(NsApplicationControlData), &ctrlSize);
|
||||
size_t jpegSize = ctrlSize - sizeof(ctrlData->nacp);
|
||||
// Grab the current user title info.
|
||||
data::userTitleInfo *userInfo = data::getCurrentUserTitleInfo();
|
||||
|
||||
fwrite(&ut->tid, sizeof(uint64_t), 1, svi);
|
||||
fwrite(&t->nacp, sizeof(NacpStruct), 1, svi);
|
||||
fwrite(ctrlData->icon, 1, jpegSize, svi);
|
||||
fclose(svi);
|
||||
delete ctrlData;
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popSVIExported", 0));
|
||||
// Use that to grab the corresponding title info.
|
||||
data::titleInfo *info = data::getTitleInfoByTID(userInfo->tid);
|
||||
|
||||
// Ensure the svi directory exists.
|
||||
std::string sviPath = fs::getWorkDir() + "svi/";
|
||||
fs::mkDir(sviPath.substr(0, sviPath.length() - 1));
|
||||
|
||||
// Append the application ID and extension.
|
||||
sviPath += util::getIDStr(userInfo->tid) + ".svi";
|
||||
|
||||
// Try to open the file for writing.
|
||||
std::FILE *sviFile = std::fopen(sviPath.data(), "wb");
|
||||
if (!sviFile)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the application ID
|
||||
std::fwrite(&userInfo->tid, 1, sizeof(uint64_t), sviFile);
|
||||
// Control data.
|
||||
std::fwrite(&info->data, 1, sizeof(NacpStruct), sviFile);
|
||||
|
||||
// Close the file.
|
||||
std::fclose(sviFile);
|
||||
|
||||
// Toast.
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("popSVIExported", 0));
|
||||
}
|
||||
|
||||
static void infoPanelDraw(void *a)
|
||||
|
|
@ -292,7 +324,13 @@ static void infoPanelDraw(void *a)
|
|||
drawY += 40;
|
||||
|
||||
gfx::drawRect(panel, &ui::rectSh, 10, drawY, rectWidth, 38);
|
||||
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 1), d->saveInfo.save_data_id);
|
||||
gfx::drawTextf(panel,
|
||||
18,
|
||||
20,
|
||||
drawY + 10,
|
||||
&ui::txtCont,
|
||||
ui::getUICString("infoStatus", 1),
|
||||
d->saveInfo.save_data_id);
|
||||
drawY += 40;
|
||||
|
||||
uint32_t hours, mins;
|
||||
|
|
@ -303,28 +341,52 @@ static void infoPanelDraw(void *a)
|
|||
drawY += 40;
|
||||
|
||||
gfx::drawRect(panel, &ui::rectSh, 10, drawY, rectWidth, 38);
|
||||
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 3), d->playStats.total_launches);
|
||||
gfx::drawTextf(panel,
|
||||
18,
|
||||
20,
|
||||
drawY + 10,
|
||||
&ui::txtCont,
|
||||
ui::getUICString("infoStatus", 3),
|
||||
d->playStats.total_launches);
|
||||
drawY += 40;
|
||||
|
||||
gfx::drawRect(panel, &ui::rectLt, 10, drawY, rectWidth, 38);
|
||||
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 5), ui::getUICString("saveDataTypeText", d->saveInfo.save_data_type));
|
||||
gfx::drawTextf(panel,
|
||||
18,
|
||||
20,
|
||||
drawY + 10,
|
||||
&ui::txtCont,
|
||||
ui::getUICString("infoStatus", 5),
|
||||
ui::getUICString("saveDataTypeText", d->saveInfo.save_data_type));
|
||||
drawY += 40;
|
||||
|
||||
uint8_t saveType = d->saveInfo.save_data_type;
|
||||
if(saveType == FsSaveDataType_Cache)
|
||||
if (saveType == FsSaveDataType_Cache)
|
||||
{
|
||||
gfx::drawRect(panel, &ui::rectSh, 10, drawY, rectWidth, 38);
|
||||
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 6), d->saveInfo.save_data_index);
|
||||
gfx::drawTextf(panel,
|
||||
18,
|
||||
20,
|
||||
drawY + 10,
|
||||
&ui::txtCont,
|
||||
ui::getUICString("infoStatus", 6),
|
||||
d->saveInfo.save_data_index);
|
||||
drawY += 40;
|
||||
}
|
||||
|
||||
gfx::drawRect(panel, saveType == FsSaveDataType_Cache ? &ui::rectLt : &ui::rectSh, 10, drawY, rectWidth, 38);
|
||||
gfx::drawTextf(panel, 18, 20, drawY + 10, &ui::txtCont, ui::getUICString("infoStatus", 7), data::getCurrentUser()->getUsername().c_str());
|
||||
gfx::drawTextf(panel,
|
||||
18,
|
||||
20,
|
||||
drawY + 10,
|
||||
&ui::txtCont,
|
||||
ui::getUICString("infoStatus", 7),
|
||||
data::getCurrentUser()->getUsername().c_str());
|
||||
}
|
||||
|
||||
static void infoPanelCallback(void *a)
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
infoPanel->closePanel();
|
||||
|
|
@ -339,7 +401,7 @@ void ui::ttlInit()
|
|||
{
|
||||
ttlHelpX = 1220 - gfx::getTextWidth(ui::getUICString("helpTitle", 0), 18);
|
||||
|
||||
for(data::user& u : data::users)
|
||||
for (data::user &u : data::users)
|
||||
ttlViews.emplace_back(new ui::titleview(u, 128, 128, 16, 16, 7, ttlViewCallback));
|
||||
|
||||
ttlOpts = new ui::menu(10, 32, 390, 20, 7);
|
||||
|
|
@ -354,7 +416,7 @@ void ui::ttlInit()
|
|||
infoPanel->setCallback(infoPanelCallback, NULL);
|
||||
|
||||
ttlOpts->setActive(false);
|
||||
for(int i = 0; i < 9; i++)
|
||||
for (int i = 0; i < 9; i++)
|
||||
ttlOpts->addOpt(NULL, ui::getUIString("titleOptions", i));
|
||||
|
||||
//Information
|
||||
|
|
@ -379,9 +441,9 @@ void ui::ttlInit()
|
|||
|
||||
void ui::ttlExit()
|
||||
{
|
||||
for(ui::titleview *t : ttlViews)
|
||||
for (ui::titleview *t : ttlViews)
|
||||
delete t;
|
||||
|
||||
|
||||
delete ttlOptsPanel;
|
||||
delete ttlOpts;
|
||||
delete infoPanel;
|
||||
|
|
@ -409,6 +471,6 @@ void ui::ttlDraw(SDL_Texture *target)
|
|||
mutexLock(&ttlViewLock);
|
||||
ttlViews[curUserIndex]->draw(target);
|
||||
mutexUnlock(&ttlViewLock);
|
||||
if(ui::mstate == TTL_SEL && !fldPanel->isOpen())
|
||||
if (ui::mstate == TTL_SEL && !fldPanel->isOpen())
|
||||
gfx::drawTextf(NULL, 18, ttlHelpX, 673, &ui::txtCont, ui::getUICString("helpTitle", 0));
|
||||
}
|
||||
|
|
|
|||
145
src/ui/usr.cpp
145
src/ui/usr.cpp
|
|
@ -1,16 +1,16 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <switch.h>
|
||||
#include <vector>
|
||||
|
||||
#include "file.h"
|
||||
#include "data.h"
|
||||
#include "file.h"
|
||||
#include "type.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
#include "type.h"
|
||||
|
||||
#include "usr.h"
|
||||
#include "ttl.h"
|
||||
#include "usr.h"
|
||||
|
||||
static const char *settText = ui::getUICString("mainMenuSettings", 0), *extText = ui::getUICString("mainMenuExtras", 0);
|
||||
|
||||
|
|
@ -34,30 +34,30 @@ 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(); )
|
||||
bool operator()(const uint64_t &tid1, const uint64_t &tid2)
|
||||
{
|
||||
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]);
|
||||
std::string tid1Title = data::getTitleNameByTID(tid1);
|
||||
std::string tid2Title = data::getTitleNameByTID(tid2);
|
||||
|
||||
pointA = tolower(pointA), pointB = tolower(pointB);
|
||||
if(pointA != pointB)
|
||||
return pointA < pointB;
|
||||
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]);
|
||||
|
||||
i += tid1Cnt, j += tid2Cnt;
|
||||
pointA = tolower(pointA), pointB = tolower(pointB);
|
||||
if (pointA != pointB)
|
||||
return pointA < pointB;
|
||||
|
||||
i += tid1Cnt, j += tid2Cnt;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} sortCreateTIDs;
|
||||
|
||||
static void onMainChange(void *a)
|
||||
{
|
||||
if(ui::usrMenu->getSelected() < (int)data::users.size())
|
||||
if (ui::usrMenu->getSelected() < (int)data::users.size())
|
||||
{
|
||||
unsigned setUser = ui::usrMenu->getSelected();
|
||||
data::setUserIndex(setUser);
|
||||
|
|
@ -87,7 +87,7 @@ static void toEXT(void *a)
|
|||
|
||||
static void usrOptCallback(void *a)
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
usrOptPanel->closePanel();
|
||||
|
|
@ -99,7 +99,7 @@ static void usrOptCallback(void *a)
|
|||
|
||||
static void saveCreateCallback(void *a)
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_B:
|
||||
usrOptMenu->setActive(true);
|
||||
|
|
@ -126,32 +126,32 @@ static void usrOptSaveCreate(void *a)
|
|||
ui::updateInput();
|
||||
int sel = m->getSelected();
|
||||
bool closeUsrOpt = false;
|
||||
if(sel == devPos && deviceSaveMenu->getOptCount() > 0)
|
||||
if (sel == devPos && deviceSaveMenu->getOptCount() > 0)
|
||||
{
|
||||
deviceSaveMenu->setActive(true);
|
||||
deviceSavePanel->openPanel();
|
||||
closeUsrOpt = true;
|
||||
}
|
||||
else if(sel == bcatPos && bcatSaveMenu->getOptCount() > 0)
|
||||
else if (sel == bcatPos && bcatSaveMenu->getOptCount() > 0)
|
||||
{
|
||||
bcatSaveMenu->setActive(true);
|
||||
bcatSavePanel->openPanel();
|
||||
closeUsrOpt = true;
|
||||
}
|
||||
else if(sel == cachePos && cacheSaveMenu->getOptCount() > 0)
|
||||
else if (sel == cachePos && cacheSaveMenu->getOptCount() > 0)
|
||||
{
|
||||
cacheSaveMenu->setActive(true);
|
||||
cacheSavePanel->openPanel();
|
||||
closeUsrOpt = true;
|
||||
}
|
||||
else if(sel < devPos)
|
||||
else if (sel < devPos)
|
||||
{
|
||||
saveCreateMenu->setActive(true);
|
||||
saveCreatePanel->openPanel();
|
||||
closeUsrOpt = true;
|
||||
}
|
||||
|
||||
if(closeUsrOpt)
|
||||
if (closeUsrOpt)
|
||||
{
|
||||
usrOptMenu->setActive(false);
|
||||
usrOptPanel->closePanel();
|
||||
|
|
@ -166,11 +166,13 @@ static void usrOptDeleteAllUserSaves_t(void *a)
|
|||
int curUserIndex = data::getCurrentUserIndex();
|
||||
int devUser = ui::usrMenu->getOptPos(ui::getUICString("saveTypeMainMenu", 0));
|
||||
|
||||
for(data::userTitleInfo& tinf : u->titleInfo)
|
||||
for (data::userTitleInfo &tinf : u->titleInfo)
|
||||
{
|
||||
if(tinf.saveInfo.save_data_type != FsSaveDataType_System && (tinf.saveInfo.save_data_type != FsSaveDataType_Device || curUserIndex == devUser))
|
||||
if (tinf.saveInfo.save_data_type != FsSaveDataType_System &&
|
||||
(tinf.saveInfo.save_data_type != FsSaveDataType_Device || curUserIndex == devUser))
|
||||
{
|
||||
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0), data::getTitleNameByTID(tinf.tid).c_str());
|
||||
t->status->setStatus(ui::getUICString("threadStatusDeletingSaveData", 0),
|
||||
data::getTitleNameByTID(tinf.tid).c_str());
|
||||
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tinf.saveInfo.save_data_id);
|
||||
}
|
||||
}
|
||||
|
|
@ -182,7 +184,12 @@ static void usrOptDeleteAllUserSaves_t(void *a)
|
|||
static void usrOptDeleteAllUserSaves(void *a)
|
||||
{
|
||||
data::user *u = data::getCurrentUser();
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(true, usrOptDeleteAllUserSaves_t, NULL, NULL, ui::getUICString("saveDataDeleteAllUser", 0), u->getUsername().c_str());
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(true,
|
||||
usrOptDeleteAllUserSaves_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ui::getUICString("saveDataDeleteAllUser", 0),
|
||||
u->getUsername().c_str());
|
||||
ui::confirm(conf);
|
||||
}
|
||||
|
||||
|
|
@ -228,9 +235,9 @@ static void createSaveData(void *a)
|
|||
|
||||
//Device, BCAT, and Cache are hardcoded user IDs in JKSV's data
|
||||
uint64_t tid = 0;
|
||||
switch(uid)
|
||||
switch (uid)
|
||||
{
|
||||
case 0://This is system
|
||||
case 0: //This is system
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
|
@ -262,20 +269,20 @@ static void usrOptCreateAllSaves_t(void *a)
|
|||
int devPos = ui::usrMenu->getOptPos(ui::getUICString("saveTypeMainMenu", 0));
|
||||
int bcatPos = ui::usrMenu->getOptPos(ui::getUICString("saveTypeMainMenu", 1));
|
||||
int sel = ui::usrMenu->getSelected();
|
||||
if(sel < devPos)
|
||||
if (sel < devPos)
|
||||
{
|
||||
AccountUid uid = u->getUID();
|
||||
for(unsigned i = 0; i < accSids.size(); i++)
|
||||
for (unsigned i = 0; i < accSids.size(); i++)
|
||||
fs::createSaveData(FsSaveDataType_Account, accSids[i], uid, t);
|
||||
}
|
||||
else if(sel == devPos)
|
||||
else if (sel == devPos)
|
||||
{
|
||||
for(unsigned i = 0; i < devSids.size(); i++)
|
||||
for (unsigned i = 0; i < devSids.size(); i++)
|
||||
fs::createSaveData(FsSaveDataType_Device, devSids[i], util::u128ToAccountUID(0), t);
|
||||
}
|
||||
else if(sel == bcatPos)
|
||||
else if (sel == bcatPos)
|
||||
{
|
||||
for(unsigned i = 0; i < bcatSids.size(); i++)
|
||||
for (unsigned i = 0; i < bcatSids.size(); i++)
|
||||
fs::createSaveData(FsSaveDataType_Bcat, bcatSids[i], util::u128ToAccountUID(0), t);
|
||||
}
|
||||
t->finished = true;
|
||||
|
|
@ -284,7 +291,12 @@ static void usrOptCreateAllSaves_t(void *a)
|
|||
static void usrOptCreateAllSaves(void *a)
|
||||
{
|
||||
data::user *u = data::getCurrentUser();
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(true, usrOptCreateAllSaves_t, NULL, NULL, ui::getUICString("confirmCreateAllSaveData", 0), u->getUsername().c_str());
|
||||
ui::confirmArgs *conf = ui::confirmArgsCreate(true,
|
||||
usrOptCreateAllSaves_t,
|
||||
NULL,
|
||||
NULL,
|
||||
ui::getUICString("confirmCreateAllSaveData", 0),
|
||||
u->getUsername().c_str());
|
||||
ui::confirm(conf);
|
||||
}
|
||||
|
||||
|
|
@ -302,20 +314,21 @@ static void initSaveCreateMenus()
|
|||
cacheSids.clear();
|
||||
|
||||
//Group into vectors to match
|
||||
for(auto& t : data::titles)
|
||||
for (auto &t : data::titles)
|
||||
{
|
||||
NacpStruct *nacp = &t.second.nacp;
|
||||
NacpStruct *nacp = &t.second.data.nacp;
|
||||
|
||||
if(nacp->user_account_save_data_size > 0)
|
||||
if (nacp->user_account_save_data_size > 0)
|
||||
accSids.push_back(t.first);
|
||||
|
||||
if(nacp->device_save_data_size > 0)
|
||||
if (nacp->device_save_data_size > 0)
|
||||
devSids.push_back(t.first);
|
||||
|
||||
if(nacp->bcat_delivery_cache_storage_size > 0)
|
||||
if (nacp->bcat_delivery_cache_storage_size > 0)
|
||||
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)
|
||||
if (nacp->cache_storage_size > 0 || nacp->cache_storage_journal_size > 0 ||
|
||||
nacp->cache_storage_data_and_journal_size_max > 0)
|
||||
cacheSids.push_back(t.first);
|
||||
}
|
||||
|
||||
|
|
@ -325,25 +338,25 @@ static void initSaveCreateMenus()
|
|||
std::sort(bcatSids.begin(), bcatSids.end(), sortCreateTIDs);
|
||||
std::sort(cacheSids.begin(), cacheSids.end(), sortCreateTIDs);
|
||||
|
||||
for(unsigned i = 0; i < accSids.size(); i++)
|
||||
for (unsigned i = 0; i < accSids.size(); i++)
|
||||
{
|
||||
saveCreateMenu->addOpt(NULL, data::getTitleNameByTID(accSids[i]));
|
||||
saveCreateMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, NULL);
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < devSids.size(); i++)
|
||||
for (unsigned i = 0; i < devSids.size(); i++)
|
||||
{
|
||||
deviceSaveMenu->addOpt(NULL, data::getTitleNameByTID(devSids[i]));
|
||||
deviceSaveMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, NULL);
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < bcatSids.size(); i++)
|
||||
for (unsigned i = 0; i < bcatSids.size(); i++)
|
||||
{
|
||||
bcatSaveMenu->addOpt(NULL, data::getTitleNameByTID(bcatSids[i]));
|
||||
bcatSaveMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, NULL);
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < cacheSids.size(); i++)
|
||||
for (unsigned i = 0; i < cacheSids.size(); i++)
|
||||
{
|
||||
cacheSaveMenu->addOpt(NULL, data::getTitleNameByTID(cacheSids[i]));
|
||||
cacheSaveMenu->optAddButtonEvent(i, HidNpadButton_A, createSaveData, NULL);
|
||||
|
|
@ -373,7 +386,7 @@ void ui::usrInit()
|
|||
cacheSaveMenu->setActive(false);
|
||||
cacheSaveMenu->setCallback(saveCreateCallback, NULL);
|
||||
|
||||
for(data::user u : data::users)
|
||||
for (data::user u : data::users)
|
||||
{
|
||||
int usrPos = usrMenu->addOpt(u.getUserIcon(), u.getUsername());
|
||||
usrMenu->optAddButtonEvent(usrPos, HidNpadButton_A, toTTL, NULL);
|
||||
|
|
@ -399,7 +412,7 @@ void ui::usrInit()
|
|||
usrOptPanel = new ui::slideOutPanel(410, 720, 0, ui::SLD_RIGHT, usrOptPanelDraw);
|
||||
ui::registerPanel(usrOptPanel);
|
||||
|
||||
for(int i = 0; i < 4; i++)
|
||||
for (int i = 0; i < 4; i++)
|
||||
usrOptMenu->addOpt(NULL, ui::getUIString("userOptions", i));
|
||||
|
||||
//Dump All User Saves
|
||||
|
|
@ -453,27 +466,27 @@ void ui::usrRefresh()
|
|||
|
||||
void ui::usrUpdate()
|
||||
{
|
||||
if(usrMenu->getActive())
|
||||
if (usrMenu->getActive())
|
||||
{
|
||||
switch(ui::padKeysDown())
|
||||
switch (ui::padKeysDown())
|
||||
{
|
||||
case HidNpadButton_Y:
|
||||
ui::newThread(fs::dumpAllUsersAllSaves, NULL, fs::fileDrawFunc);
|
||||
break;
|
||||
|
||||
case HidNpadButton_X:
|
||||
{
|
||||
int cachePos = usrMenu->getOptPos(ui::getUIString("saveTypeMainMenu", 2));
|
||||
if (usrMenu->getSelected() <= cachePos)
|
||||
{
|
||||
int cachePos = usrMenu->getOptPos(ui::getUIString("saveTypeMainMenu", 2));
|
||||
if(usrMenu->getSelected() <= cachePos)
|
||||
{
|
||||
data::user *u = data::getCurrentUser();
|
||||
usrOptMenu->editOpt(0, NULL, ui::getUIString("userOptions", 0) + u->getUsername());
|
||||
usrOptMenu->setActive(true);
|
||||
usrMenu->setActive(false);
|
||||
usrOptPanel->openPanel();
|
||||
}
|
||||
data::user *u = data::getCurrentUser();
|
||||
usrOptMenu->editOpt(0, NULL, ui::getUIString("userOptions", 0) + u->getUsername());
|
||||
usrOptMenu->setActive(true);
|
||||
usrMenu->setActive(false);
|
||||
usrOptPanel->openPanel();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
usrMenu->update();
|
||||
|
|
@ -486,6 +499,6 @@ void ui::usrUpdate()
|
|||
|
||||
void ui::usrDraw(SDL_Texture *target)
|
||||
{
|
||||
if(ui::mstate == USR_SEL)
|
||||
if (ui::mstate == USR_SEL)
|
||||
gfx::drawTextf(NULL, 18, usrHelpX, 673, &ui::txtCont, ui::getUICString("helpUser", 0));
|
||||
}
|
||||
|
|
|
|||
163
src/util.cpp
163
src/util.cpp
|
|
@ -1,40 +1,40 @@
|
|||
#include <string>
|
||||
#include <cstdio>
|
||||
#include <ctime>
|
||||
#include <sys/stat.h>
|
||||
#include <json-c/json.h>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "data.h"
|
||||
#include "gfx.h"
|
||||
#include "util.h"
|
||||
#include "ui.h"
|
||||
#include "curlfuncs.h"
|
||||
#include "type.h"
|
||||
#include "cfg.h"
|
||||
#include "curlfuncs.h"
|
||||
#include "data.h"
|
||||
#include "file.h"
|
||||
#include "gfx.h"
|
||||
#include "type.h"
|
||||
#include "ui.h"
|
||||
#include "util.h"
|
||||
|
||||
static const uint32_t verboten[] = { L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*', L'™', L'©', L'®'};
|
||||
static const uint32_t verboten[] = {L',', L'/', L'\\', L'<', L'>', L':', L'"', L'|', L'?', L'*', L'™', L'©', L'®'};
|
||||
|
||||
static bool isVerboten(const uint32_t& t)
|
||||
static bool isVerboten(const uint32_t &t)
|
||||
{
|
||||
for(unsigned i = 0; i < 13; i++)
|
||||
for (unsigned i = 0; i < 13; i++)
|
||||
{
|
||||
if(t == verboten[i])
|
||||
if (t == verboten[i])
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void util::replaceStr(std::string& _str, const std::string& _find, const std::string& _rep)
|
||||
void util::replaceStr(std::string &_str, const std::string &_find, const std::string &_rep)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = _str.find(_find)) != _str.npos)
|
||||
while ((pos = _str.find(_find)) != _str.npos)
|
||||
_str.replace(pos, _find.length(), _rep);
|
||||
}
|
||||
|
||||
//Used to split version tag git
|
||||
static void getVersionFromTag(const std::string& tag, unsigned& _year, unsigned& _month, unsigned& _day)
|
||||
static void getVersionFromTag(const std::string &tag, unsigned &_year, unsigned &_month, unsigned &_day)
|
||||
{
|
||||
_month = strtoul(tag.substr(0, 2).c_str(), NULL, 10);
|
||||
_day = strtoul(tag.substr(3, 5).c_str(), NULL, 10);
|
||||
|
|
@ -45,13 +45,13 @@ static void getVersionFromTag(const std::string& tag, unsigned& _year, unsigned&
|
|||
typedef enum
|
||||
{
|
||||
SwkbdPosStart = 0,
|
||||
SwkbdPosEnd = 1
|
||||
SwkbdPosEnd = 1
|
||||
} SwkbdInitPos;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t read[0x32 / sizeof(uint16_t)];
|
||||
uint16_t word[0x32 / sizeof(uint16_t)];
|
||||
uint16_t read[0x32 / sizeof(uint16_t)];
|
||||
uint16_t word[0x32 / sizeof(uint16_t)];
|
||||
} dictWord;
|
||||
|
||||
void swkbdDictWordCreate(dictWord *w, const char *read, const char *word)
|
||||
|
|
@ -64,7 +64,7 @@ void swkbdDictWordCreate(dictWord *w, const char *read, const char *word)
|
|||
|
||||
uint32_t replaceChar(uint32_t c)
|
||||
{
|
||||
switch(c)
|
||||
switch (c)
|
||||
{
|
||||
case L'é':
|
||||
return 'e';
|
||||
|
|
@ -77,9 +77,9 @@ uint32_t replaceChar(uint32_t c)
|
|||
static inline void replaceCharCStr(char *_s, char _find, char _rep)
|
||||
{
|
||||
size_t strLength = strlen(_s);
|
||||
for(unsigned i = 0; i < strLength; i++)
|
||||
for (unsigned i = 0; i < strLength; i++)
|
||||
{
|
||||
if(_s[i] == _find)
|
||||
if (_s[i] == _find)
|
||||
_s[i] = _rep;
|
||||
}
|
||||
}
|
||||
|
|
@ -92,14 +92,28 @@ std::string util::getDateTime(int fmt)
|
|||
time(&raw);
|
||||
tm *Time = localtime(&raw);
|
||||
|
||||
switch(fmt)
|
||||
switch (fmt)
|
||||
{
|
||||
case DATE_FMT_YMD:
|
||||
sprintf(ret, "%04d.%02d.%02d @ %02d.%02d.%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min, Time->tm_sec);
|
||||
sprintf(ret,
|
||||
"%04d.%02d.%02d @ %02d.%02d.%02d",
|
||||
Time->tm_year + 1900,
|
||||
Time->tm_mon + 1,
|
||||
Time->tm_mday,
|
||||
Time->tm_hour,
|
||||
Time->tm_min,
|
||||
Time->tm_sec);
|
||||
break;
|
||||
|
||||
case DATE_FMT_YDM:
|
||||
sprintf(ret, "%04d.%02d.%02d @ %02d.%02d.%02d", Time->tm_year + 1900, Time->tm_mday, Time->tm_mon + 1, Time->tm_hour, Time->tm_min, Time->tm_sec);
|
||||
sprintf(ret,
|
||||
"%04d.%02d.%02d @ %02d.%02d.%02d",
|
||||
Time->tm_year + 1900,
|
||||
Time->tm_mday,
|
||||
Time->tm_mon + 1,
|
||||
Time->tm_hour,
|
||||
Time->tm_min,
|
||||
Time->tm_sec);
|
||||
break;
|
||||
|
||||
case DATE_FMT_HOYSTE:
|
||||
|
|
@ -107,7 +121,13 @@ std::string util::getDateTime(int fmt)
|
|||
break;
|
||||
|
||||
case DATE_FMT_JHK:
|
||||
sprintf(ret, "%04d%02d%02d_%02d%02d", Time->tm_year + 1900, Time->tm_mon + 1, Time->tm_mday, Time->tm_hour, Time->tm_min);
|
||||
sprintf(ret,
|
||||
"%04d%02d%02d_%02d%02d",
|
||||
Time->tm_year + 1900,
|
||||
Time->tm_mon + 1,
|
||||
Time->tm_mday,
|
||||
Time->tm_hour,
|
||||
Time->tm_min);
|
||||
break;
|
||||
|
||||
case DATE_FMT_ASC:
|
||||
|
|
@ -120,47 +140,47 @@ std::string util::getDateTime(int fmt)
|
|||
return std::string(ret);
|
||||
}
|
||||
|
||||
void util::copyDirListToMenu(const fs::dirList& d, ui::menu& m)
|
||||
void util::copyDirListToMenu(const fs::dirList &d, ui::menu &m)
|
||||
{
|
||||
m.reset();
|
||||
m.addOpt(NULL, ".");
|
||||
m.addOpt(NULL, "..");
|
||||
for(unsigned i = 0; i < d.getCount(); i++)
|
||||
for (unsigned i = 0; i < d.getCount(); i++)
|
||||
{
|
||||
if(d.isDir(i))
|
||||
if (d.isDir(i))
|
||||
m.addOpt(NULL, "D " + d.getItem(i));
|
||||
else
|
||||
m.addOpt(NULL, "F " + d.getItem(i));
|
||||
}
|
||||
}
|
||||
|
||||
void util::removeLastFolderFromString(std::string& _path)
|
||||
void util::removeLastFolderFromString(std::string &_path)
|
||||
{
|
||||
unsigned last = _path.find_last_of('/', _path.length() - 2);
|
||||
_path.erase(last + 1, _path.length());
|
||||
}
|
||||
|
||||
size_t util::getTotalPlacesInPath(const std::string& _path)
|
||||
size_t util::getTotalPlacesInPath(const std::string &_path)
|
||||
{
|
||||
//Skip device
|
||||
size_t pos = _path.find_first_of('/'), ret = 0;
|
||||
while((pos = _path.find_first_of('/', ++pos)) != _path.npos)
|
||||
while ((pos = _path.find_first_of('/', ++pos)) != _path.npos)
|
||||
++ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void util::trimPath(std::string& _path, uint8_t _places)
|
||||
void util::trimPath(std::string &_path, uint8_t _places)
|
||||
{
|
||||
size_t pos = _path.find_first_of('/');
|
||||
for(int i = 0; i < _places; i++)
|
||||
for (int i = 0; i < _places; i++)
|
||||
pos = _path.find_first_of('/', ++pos);
|
||||
_path = _path.substr(++pos, _path.npos);
|
||||
}
|
||||
|
||||
std::string util::safeString(const std::string& s)
|
||||
std::string util::safeString(const std::string &s)
|
||||
{
|
||||
std::string ret = "";
|
||||
for(unsigned i = 0; i < s.length(); )
|
||||
for (unsigned i = 0; i < s.length();)
|
||||
{
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t untCnt = decode_utf8(&tmpChr, (uint8_t *)&s.data()[i]);
|
||||
|
|
@ -169,29 +189,34 @@ std::string util::safeString(const std::string& s)
|
|||
|
||||
tmpChr = replaceChar(tmpChr);
|
||||
|
||||
if(isVerboten(tmpChr))
|
||||
if (isVerboten(tmpChr))
|
||||
ret += ' ';
|
||||
else if(!isASCII(tmpChr))
|
||||
else if (!isASCII(tmpChr))
|
||||
return ""; //return empty string so titledata::init defaults to titleID
|
||||
else
|
||||
ret += (char)tmpChr;
|
||||
}
|
||||
|
||||
//Check for spaces at end
|
||||
while(ret[ret.length() - 1] == ' ' || ret[ret.length() - 1] == '.')
|
||||
while (ret[ret.length() - 1] == ' ' || ret[ret.length() - 1] == '.')
|
||||
ret.erase(ret.length() - 1, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline std::string getTimeString(const uint32_t& _h, const uint32_t& _m)
|
||||
static inline std::string getTimeString(const uint32_t &_h, const uint32_t &_m)
|
||||
{
|
||||
char tmp[32];
|
||||
sprintf(tmp, "%02d:%02d", _h, _m);
|
||||
return std::string(tmp);
|
||||
}
|
||||
|
||||
std::string util::getStringInput(SwkbdType _type, const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[])
|
||||
std::string util::getStringInput(SwkbdType _type,
|
||||
const std::string &def,
|
||||
const std::string &head,
|
||||
size_t maxLength,
|
||||
unsigned dictCnt,
|
||||
const std::string dictWords[])
|
||||
{
|
||||
SwkbdConfig swkbd;
|
||||
swkbdCreate(&swkbd, dictCnt);
|
||||
|
|
@ -205,10 +230,10 @@ std::string util::getStringInput(SwkbdType _type, const std::string& def, const
|
|||
swkbdConfigSetKeySetDisableBitmask(&swkbd, SwkbdKeyDisableBitmask_Backslash | SwkbdKeyDisableBitmask_Percent);
|
||||
swkbdConfigSetDicFlag(&swkbd, 1);
|
||||
|
||||
if(dictCnt > 0)
|
||||
if (dictCnt > 0)
|
||||
{
|
||||
dictWord words[dictCnt];
|
||||
for(unsigned i = 0; i < dictCnt; i++)
|
||||
for (unsigned i = 0; i < dictCnt; i++)
|
||||
swkbdDictWordCreate(&words[i], dictWords[i].c_str(), dictWords[i].c_str());
|
||||
|
||||
swkbdConfigSetDictionary(&swkbd, (SwkbdDictWord *)words, dictCnt);
|
||||
|
|
@ -222,25 +247,25 @@ std::string util::getStringInput(SwkbdType _type, const std::string& def, const
|
|||
return std::string(out);
|
||||
}
|
||||
|
||||
std::string util::getExtensionFromString(const std::string& get)
|
||||
std::string util::getExtensionFromString(const std::string &get)
|
||||
{
|
||||
size_t ext = get.find_last_of('.');
|
||||
if(ext != get.npos)
|
||||
if (ext != get.npos)
|
||||
return get.substr(ext + 1, get.npos);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string util::getFilenameFromPath(const std::string& get)
|
||||
std::string util::getFilenameFromPath(const std::string &get)
|
||||
{
|
||||
size_t nameStart = get.find_last_of('/');
|
||||
if(nameStart != get.npos)
|
||||
if (nameStart != get.npos)
|
||||
return get.substr(nameStart + 1, get.npos);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string util::generateAbbrev(const uint64_t& tid)
|
||||
std::string util::generateAbbrev(uint64_t tid)
|
||||
{
|
||||
data::titleInfo *tmp = data::getTitleInfoByTID(tid);
|
||||
size_t titleLength = tmp->safeTitle.length();
|
||||
|
|
@ -251,23 +276,23 @@ std::string util::generateAbbrev(const uint64_t& tid)
|
|||
|
||||
std::string ret;
|
||||
char *tok = strtok(temp, " ");
|
||||
while(tok)
|
||||
while (tok)
|
||||
{
|
||||
if(isASCII(tok[0]))
|
||||
if (isASCII(tok[0]))
|
||||
ret += tok[0];
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void util::stripChar(char _c, std::string& _s)
|
||||
void util::stripChar(char _c, std::string &_s)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = _s.find(_c)) != _s.npos)
|
||||
while ((pos = _s.find(_c)) != _s.npos)
|
||||
_s.erase(pos, 1);
|
||||
}
|
||||
|
||||
void util::replaceButtonsInString(std::string& rep)
|
||||
void util::replaceButtonsInString(std::string &rep)
|
||||
{
|
||||
replaceStr(rep, "[A]", "\ue0e0");
|
||||
replaceStr(rep, "[B]", "\ue0e1");
|
||||
|
|
@ -292,7 +317,7 @@ SDL_Texture *util::createIconGeneric(const char *txt, int fontSize, bool clearBa
|
|||
{
|
||||
SDL_Texture *ret = gfx::texMgr->textureCreate(256, 256);
|
||||
SDL_SetRenderTarget(gfx::render, ret);
|
||||
if(clearBack)
|
||||
if (clearBack)
|
||||
{
|
||||
SDL_SetRenderDrawColor(gfx::render, ui::rectLt.r, ui::rectLt.g, ui::rectLt.b, ui::rectLt.a);
|
||||
SDL_RenderClear(gfx::render);
|
||||
|
|
@ -310,7 +335,7 @@ SDL_Texture *util::createIconGeneric(const char *txt, int fontSize, bool clearBa
|
|||
|
||||
void util::sysBoost()
|
||||
{
|
||||
if(R_FAILED(clkrstInitialize()))
|
||||
if (R_FAILED(clkrstInitialize()))
|
||||
return;
|
||||
|
||||
ClkrstSession cpu, gpu, ram;
|
||||
|
|
@ -330,7 +355,7 @@ void util::sysBoost()
|
|||
|
||||
void util::sysNormal()
|
||||
{
|
||||
if(R_FAILED(clkrstInitialize()))
|
||||
if (R_FAILED(clkrstInitialize()))
|
||||
return;
|
||||
|
||||
ClkrstSession cpu, gpu, ram;
|
||||
|
|
@ -338,7 +363,7 @@ void util::sysNormal()
|
|||
clkrstOpenSession(&gpu, PcvModuleId_GPU, 3);
|
||||
clkrstOpenSession(&ram, PcvModuleId_EMC, 3);
|
||||
|
||||
if(cfg::config["ovrClk"])
|
||||
if (cfg::config["ovrClk"])
|
||||
clkrstSetClockRate(&cpu, util::CPU_SPEED_1224MHz);
|
||||
else
|
||||
clkrstSetClockRate(&cpu, util::CPU_SPEED_1020MHz);
|
||||
|
|
@ -349,7 +374,6 @@ void util::sysNormal()
|
|||
clkrstCloseSession(&gpu);
|
||||
clkrstCloseSession(&ram);
|
||||
clkrstExit();
|
||||
|
||||
}
|
||||
|
||||
void util::checkForUpdate(void *a)
|
||||
|
|
@ -357,7 +381,7 @@ void util::checkForUpdate(void *a)
|
|||
threadInfo *t = (threadInfo *)a;
|
||||
t->status->setStatus(ui::getUICString("threadStatusCheckingForUpdate", 0));
|
||||
std::string gitJson = curlFuncs::getJSONURL(NULL, "https://api.github.com/repos/J-D-K/JKSV/releases/latest");
|
||||
if(gitJson.empty())
|
||||
if (gitJson.empty())
|
||||
{
|
||||
ui::showPopMessage(POP_FRAME_DEFAULT, ui::getUICString("onlineErrorConnecting", 0));
|
||||
t->finished = true;
|
||||
|
|
@ -371,7 +395,7 @@ void util::checkForUpdate(void *a)
|
|||
tagStr = json_object_get_string(tag);
|
||||
getVersionFromTag(tagStr, year, month, day);
|
||||
//This can throw false positives as is. need to fix sometime
|
||||
if(year > BLD_YEAR || month > BLD_MON || month > BLD_DAY)
|
||||
if (year > BLD_YEAR || month > BLD_MON || month > BLD_DAY)
|
||||
{
|
||||
t->status->setStatus(ui::getUICString("threadStatusDownloadingUpdate", 0));
|
||||
//dunno about NSP yet...
|
||||
|
|
@ -394,27 +418,16 @@ void util::checkForUpdate(void *a)
|
|||
t->finished = true;
|
||||
}
|
||||
|
||||
std::string util::getSizeString(const uint64_t& _size)
|
||||
std::string util::getSizeString(uint64_t _size)
|
||||
{
|
||||
char sizeStr[32];
|
||||
if(_size >= 0x40000000)
|
||||
if (_size >= 0x40000000)
|
||||
sprintf(sizeStr, "%.2fGB", (float)_size / 1024.0f / 1024.0f / 1024.0f);
|
||||
else if(_size >= 0x100000)
|
||||
else if (_size >= 0x100000)
|
||||
sprintf(sizeStr, "%.2fMB", (float)_size / 1024.0f / 1024.0f);
|
||||
else if(_size >= 0x400)
|
||||
else if (_size >= 0x400)
|
||||
sprintf(sizeStr, "%.2fKB", (float)_size / 1024.0f);
|
||||
else
|
||||
sprintf(sizeStr, "%lu Bytes", _size);
|
||||
return std::string(sizeStr);
|
||||
}
|
||||
|
||||
Result util::accountDeleteUser(AccountUid *uid)
|
||||
{
|
||||
Service *account = accountGetServiceSession();
|
||||
struct
|
||||
{
|
||||
AccountUid uid;
|
||||
} in = {*uid};
|
||||
|
||||
return serviceDispatchIn(account, 203, in);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user