mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-04-24 23:37:24 -05:00
Remove namespace from source files, add more text to translation text, add place holder files for translations, make folder menus share functions
This commit is contained in:
parent
2dc96be0b8
commit
bdd1a1d88d
2
Makefile
2
Makefile
|
|
@ -38,7 +38,7 @@ INCLUDES := inc
|
|||
EXEFS_SRC := exefs_src
|
||||
APP_TITLE := JKSV
|
||||
APP_AUTHOR := JK
|
||||
APP_VERSION := 05.20.2020
|
||||
APP_VERSION := 05.22.2020
|
||||
ROMFS := romfs
|
||||
ICON := romfs/icon.jpg
|
||||
|
||||
|
|
|
|||
12
inc/file.h
12
inc/file.h
|
|
@ -90,11 +90,19 @@ namespace fs
|
|||
|
||||
bool isOpen() { return opened; }
|
||||
|
||||
//Gets next good line. Returns empty string if no more.
|
||||
std::string getNextLine();
|
||||
bool readNextLine(bool proc);
|
||||
//Finds where variable name ends. When a '(' or '=' is hit. Strips spaces
|
||||
void procLine();
|
||||
std::string getLine() { return line; }
|
||||
std::string getName() { return name; }
|
||||
//Reads until ';', ',', or '\n' is hit and returns as string.
|
||||
std::string getNextValueStr();
|
||||
int getNextValueInt();
|
||||
|
||||
private:
|
||||
FILE *f;
|
||||
std::string line, name;
|
||||
size_t lPos = 0;
|
||||
bool opened = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ typedef struct
|
|||
int fsremove(const char *_p);
|
||||
Result fsDelDirRec(const char *_p);
|
||||
|
||||
char *getDeviceFromPath(char *dev, size_t _max, const char *path);
|
||||
char *getFilePath(char *pathOut, size_t _max, const char *path);
|
||||
|
||||
/*Opens file. Device is fetched from path. Libnx romfs doesn't work with this.
|
||||
Mode needs to be:
|
||||
FsOpenMode_Read
|
||||
|
|
|
|||
16
inc/miscui.h
16
inc/miscui.h
|
|
@ -3,22 +3,6 @@
|
|||
|
||||
#include "gfx.h"
|
||||
|
||||
enum buttonEvents
|
||||
{
|
||||
BUTTON_NOTHING,
|
||||
BUTTON_PRESSED,
|
||||
BUTTON_RELEASED
|
||||
};
|
||||
|
||||
enum trackEvents
|
||||
{
|
||||
TRACK_NOTHING,
|
||||
TRACK_SWIPE_UP,
|
||||
TRACK_SWIPE_DOWN,
|
||||
TRACK_SWIPE_LEFT,
|
||||
TRACK_SWIPE_RIGHT
|
||||
};
|
||||
|
||||
#define POP_FRAME_DEFAULT 130
|
||||
|
||||
//For smaller classes that aren't easy to get lost in and general functions
|
||||
|
|
|
|||
19
inc/ui.h
19
inc/ui.h
|
|
@ -40,10 +40,17 @@ namespace ui
|
|||
//Both UI modes need access to this
|
||||
extern std::string folderMenuInfo;
|
||||
|
||||
//Strings since translation support soonish
|
||||
//Strings since translation support
|
||||
extern std::string userHelp, titleHelp, folderHelp, optHelp, \
|
||||
confBlackList, confOverwrite, confRestore, confDel, confCopy, \
|
||||
confEraseNand, confEraseFolder, yt, nt;
|
||||
confBlacklist, confOverwrite, confRestore, confDel, confCopy, \
|
||||
confEraseNand, confEraseFolder, yt, nt, on, off;
|
||||
|
||||
//Strings for file mode menu
|
||||
extern std::string advMenuStr[6];
|
||||
//Strings for extras menu
|
||||
extern std::string exMenuStr[10];
|
||||
//Strings for options menu
|
||||
extern std::string optMenuStr[12];
|
||||
|
||||
/*Colors
|
||||
clearClr = color to clear buffer
|
||||
|
|
@ -81,6 +88,12 @@ namespace ui
|
|||
|
||||
//switch case so we don't have problems with multiple main loops like 3DS
|
||||
void runApp(const uint64_t& down, const uint64_t& held);
|
||||
|
||||
//These are shared by both folder menus
|
||||
void createNewBackup(const uint64_t& held);
|
||||
void overwriteBackup(unsigned ind);
|
||||
void restoreBackup(unsigned ind);
|
||||
void deleteBackup(unsigned ind);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -34,8 +34,8 @@ namespace util
|
|||
|
||||
std::string generateAbbrev(data::titledata& dat);
|
||||
|
||||
//removes newline '\n' chars from string
|
||||
void stripNL(std::string& _s);
|
||||
//removes char from C++ string
|
||||
void stripChar(char _c, std::string& _s);
|
||||
|
||||
//For future external translation support. Replaces [button] with button chars
|
||||
void replaceButtonsInString(std::string& rep);
|
||||
|
|
|
|||
2
romfs/lang/de.txt
Normal file
2
romfs/lang/de.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Deutsch translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/en-GB.txt
Normal file
2
romfs/lang/en-GB.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#British English translation file
|
||||
#Copy en-US.txt here and add a bunch of u's where they don't belong.
|
||||
|
|
@ -1,45 +1,86 @@
|
|||
#This file's strings must be kept in this order. Lines starting with '#' will be ignored.
|
||||
#Not sure yet if the whole thing needs to be translated or just important things
|
||||
#Button strings [X] are replaced by JKSV at boot.
|
||||
|
||||
#string = set string to this.
|
||||
#Translation author. Displayed in UI. NULL is ignored and not displayed.
|
||||
NULL
|
||||
author = NULL
|
||||
|
||||
#Help/Guide strings on bottom
|
||||
#User Select
|
||||
[A] Select [Y] Dump All [X] UI Mode [-] Options [ZR] Extras
|
||||
userHelp = [A] Select [Y] Dump All [X] UI Mode [-] Options [ZR] Extras
|
||||
|
||||
#Title Select
|
||||
[A] Select [L][R] Change User [Y] Dump All [-] Favorite [X] BlackList [ZR] Erase [B] Back
|
||||
titleHelp = [A] Select [L][R] Change User [Y] Dump All [X] Favorite [-] BlackList [ZR] Erase [B] Back
|
||||
|
||||
#Folder Select
|
||||
[-] File Mode [L][R] Auto [A] Backup [Y] Restore [X] Delete Folder [ZR] Erase [B] Back
|
||||
folderHelp = [-] File Mode [L][R] Auto [A] Backup [Y] Restore [X] Delete Folder [ZR] Erase [B] Back
|
||||
|
||||
#Options Menu
|
||||
[A] Toggle [B] Back
|
||||
optHelp = [A] Toggle [B] Back
|
||||
|
||||
#Button prompts.
|
||||
Yes [A]
|
||||
No [B]
|
||||
yt = Yes [A]
|
||||
nt = No [B]
|
||||
|
||||
#On/Off for options. '>' is used to change color to green.
|
||||
on = >On>
|
||||
off = Off
|
||||
|
||||
#Strings for messages/confirmation. '*' and '#' are used in strings to change color. %s is replaced with titles and names.
|
||||
#Confirm blacklist.
|
||||
Are you sure you want to add #%s# to your blacklist?
|
||||
confirmBlacklist = Are you sure you want to add #%s# to your blacklist?
|
||||
|
||||
#Confirm overwriting folder
|
||||
Are you sure you want to overwrite #%s#?
|
||||
confirmOverwrite = Are you sure you want to overwrite #%s#?
|
||||
|
||||
#Confirm restoring save
|
||||
Are you sure you want to restore #%s#?
|
||||
confirmRestore = Are you sure you want to restore #%s#?
|
||||
|
||||
#Confirm deleting.
|
||||
Are you sure you want to delete #%s#? *This is permanent*!
|
||||
confirmDelete = Are you sure you want to delete #%s#? *This is permanent*!
|
||||
|
||||
#Confirm file copy in file mode
|
||||
Are you sure you want to copy #%s# to #%s#?
|
||||
confirmCopy = Are you sure you want to copy #%s# to #%s#?
|
||||
|
||||
#Warning for erasing save data from system in title menu
|
||||
*WARNING*: This *will* erase the save data for #%s# *from your system*. This is the same as deleting it from #Data Management#! Are you sure you want to continue?
|
||||
confirmEraseNand = *WARNING*: This *will* erase the save data for #%s# *from your system*. This is the same as deleting it from #Data Management#! Are you sure you want to continue?
|
||||
|
||||
#Warning for deleting save data in folder menu
|
||||
*WARNING*: This *will* delete the current save data for #%s# *from your system*! Are you sure you want to continue?
|
||||
confirmEraseFolder = *WARNING*: This *will* delete the current save data for #%s# *from your system*! Are you sure you want to continue?
|
||||
|
||||
#Menu options are held in arrays of strings.
|
||||
#The number is the option to set, string is what to set to.
|
||||
#Only the string after the comma needs to be edited.
|
||||
#Adv/file mode menu
|
||||
#'Copy to ' NEEDS a trailing space
|
||||
advMenu = 0, Copy to
|
||||
advMenu = 1, Delete
|
||||
advMenu = 2, Rename
|
||||
advMenu = 3, Make Dir
|
||||
advMenu = 4, Properties
|
||||
advMenu = 5, Close
|
||||
|
||||
#Extras Menu
|
||||
extMenu = 0, SD to SD Browser
|
||||
extMenu = 1, BIS: PRODINFOF
|
||||
extMenu = 2, BIS: SAFE
|
||||
extMenu = 3, BIS: SYSTEM
|
||||
extMenu = 4, BIS: USER
|
||||
extMenu = 5, Remove Update
|
||||
extMenu = 6, Terminate Process
|
||||
extMenu = 7, Mount System Save
|
||||
extMenu = 8, Rescan Titles
|
||||
extMenu = 9, Process RomFS
|
||||
|
||||
#Options menu
|
||||
#This is always last and all need a trailing space. It is the most likely to have things added to it.
|
||||
optMenu = 0, Include Dev Sv:
|
||||
optMenu = 1, AutoBackup:
|
||||
optMenu = 2, Overclock:
|
||||
optMenu = 3, Hold to Delete:
|
||||
optMenu = 4, Hold to Restore:
|
||||
optMenu = 5, Hold to Overwrite:
|
||||
optMenu = 6, Force Mount:
|
||||
optMenu = 7, Account Sys. Saves:
|
||||
optMenu = 8, Write to Sys. Saves:
|
||||
optMenu = 9, Text UI Mode:
|
||||
optMenu = 10, Direct FS Cmd:
|
||||
optMenu = 11, Skip User Select:
|
||||
2
romfs/lang/es-419.txt
Normal file
2
romfs/lang/es-419.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Latin American Spanish translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/es.txt
Normal file
2
romfs/lang/es.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Spanish(Spain) translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/fr-CA.txt
Normal file
2
romfs/lang/fr-CA.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Canadian French translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/fr.txt
Normal file
2
romfs/lang/fr.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#French(France) French translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/it.txt
Normal file
2
romfs/lang/it.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Italian translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/ja.txt
Normal file
2
romfs/lang/ja.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Japanese translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/ko.txt
Normal file
2
romfs/lang/ko.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Korean translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/nl.txt
Normal file
2
romfs/lang/nl.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Dutch translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/pt.txt
Normal file
2
romfs/lang/pt.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Portugeuse translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/ru.txt
Normal file
2
romfs/lang/ru.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Russian translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/zh-CN.txt
Normal file
2
romfs/lang/zh-CN.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Chinese translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
2
romfs/lang/zh-TW.txt
Normal file
2
romfs/lang/zh-TW.txt
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#Taiwanese translation file
|
||||
#Copy en-US.txt here and use as a guide.
|
||||
956
src/data.cpp
956
src/data.cpp
File diff suppressed because it is too large
Load Diff
889
src/file.cpp
889
src/file.cpp
|
|
@ -184,443 +184,466 @@ static void mkdirRec(const std::string& _p)
|
|||
}
|
||||
}
|
||||
|
||||
namespace fs
|
||||
|
||||
void fs::init()
|
||||
{
|
||||
void init()
|
||||
{
|
||||
if(fs::fileExists("sdmc:/switch/jksv_dir.txt"))
|
||||
{
|
||||
char tmp[256];
|
||||
FILE *getDir = fopen("sdmc:/switch/jksv_dir.txt", "r");
|
||||
fgets(tmp, 256, getDir);
|
||||
fclose(getDir);
|
||||
wd = tmp;
|
||||
util::stripNL(wd);
|
||||
mkdirRec(wd);
|
||||
}
|
||||
else
|
||||
{
|
||||
mkdir("sdmc:/JKSV", 777);
|
||||
wd = "sdmc:/JKSV/";
|
||||
}
|
||||
fs::logOpen();
|
||||
}
|
||||
|
||||
void exit()
|
||||
{
|
||||
fs::logClose();
|
||||
}
|
||||
|
||||
bool mountSave(data::user& usr, data::titledata& open)
|
||||
{
|
||||
Result svOpen;
|
||||
FsFileSystem sv;
|
||||
|
||||
switch(open.getType())
|
||||
{
|
||||
case FsSaveDataType_System:
|
||||
svOpen = fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, open.getID(), usr.getUID128() == 1 ? (AccountUid) { 0 } : usr.getUID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Account:
|
||||
svOpen = fsOpen_SaveData(&sv, open.getID(), usr.getUID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
svOpen = fsOpen_BcatSaveData(&sv, open.getID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
svOpen = fsOpen_DeviceSaveData(&sv, open.getID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Temporary:
|
||||
svOpen = fsOpen_TemporaryStorage(&sv);
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
svOpen = fsOpen_CacheStorage(&sv, open.getID(), open.getSaveIndex());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_SystemBcat:
|
||||
svOpen = fsOpen_SystemBcatSaveData(&sv, open.getID());
|
||||
break;
|
||||
|
||||
default:
|
||||
svOpen = 1;
|
||||
break;
|
||||
}
|
||||
return R_SUCCEEDED(svOpen) && fsdevMountDevice("sv", sv) != -1;
|
||||
}
|
||||
|
||||
dirItem::dirItem(const std::string& pathTo, const std::string& sItem)
|
||||
{
|
||||
itm = sItem;
|
||||
|
||||
std::string fullPath = pathTo + sItem;
|
||||
struct stat s;
|
||||
if(stat(fullPath.c_str(), &s) == 0 && S_ISDIR(s.st_mode))
|
||||
dir = true;
|
||||
}
|
||||
|
||||
dirList::dirList(const std::string& _path)
|
||||
{
|
||||
path = _path;
|
||||
d = opendir(path.c_str());
|
||||
|
||||
while((ent = readdir(d)))
|
||||
{
|
||||
dirItem add(path, ent->d_name);
|
||||
item.push_back(add);
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
std::sort(item.begin(), item.end(), sortDirList);
|
||||
}
|
||||
|
||||
void dirList::reassign(const std::string& _path)
|
||||
{
|
||||
path = _path;
|
||||
|
||||
d = opendir(path.c_str());
|
||||
|
||||
item.clear();
|
||||
|
||||
while((ent = readdir(d)))
|
||||
{
|
||||
dirItem add(path, ent->d_name);
|
||||
item.push_back(add);
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
std::sort(item.begin(), item.end(), sortDirList);
|
||||
}
|
||||
|
||||
void dirList::rescan()
|
||||
{
|
||||
item.clear();
|
||||
d = opendir(path.c_str());
|
||||
|
||||
while((ent = readdir(d)))
|
||||
{
|
||||
dirItem add(path, ent->d_name);
|
||||
item.push_back(add);
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
std::sort(item.begin(), item.end(), sortDirList);
|
||||
}
|
||||
|
||||
dataFile::dataFile(const std::string& _path)
|
||||
{
|
||||
f = fopen(_path.c_str(), "r");
|
||||
if(f != NULL)
|
||||
opened = true;
|
||||
}
|
||||
|
||||
dataFile::~dataFile()
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
std::string dataFile::getNextLine()
|
||||
{
|
||||
std::string ret = "";
|
||||
char tmp[1024];
|
||||
while(fgets(tmp, 1024, f))
|
||||
{
|
||||
if(tmp[0] != '#' && tmp[0] != '\n')
|
||||
{
|
||||
ret = tmp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
util::stripNL(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void copyFile(const std::string& from, const std::string& to)
|
||||
{
|
||||
Thread cpyThread;
|
||||
uint64_t gProg = 0;
|
||||
copyArgs *thr = copyArgsCreate(from, to, "", &gProg);
|
||||
if(data::directFsCmd)
|
||||
threadCreate(&cpyThread, copyfileFS_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
else
|
||||
threadCreate(&cpyThread, copyfile_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
|
||||
ui::progBar fileProg(fsize(from));
|
||||
threadStart(&cpyThread);
|
||||
while(!thr->fin)
|
||||
{
|
||||
fileProg.update(*thr->pos);
|
||||
gfxBeginFrame();
|
||||
fileProg.draw(from, "Copying File...");
|
||||
gfxEndFrame();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
delete thr;
|
||||
}
|
||||
|
||||
void copyFileCommit(const std::string& from, const std::string& to, const std::string& dev)
|
||||
{
|
||||
Thread cpyThread;
|
||||
uint64_t gProg = 0;
|
||||
copyArgs *thr = copyArgsCreate(from, to, dev, &gProg);
|
||||
if(data::directFsCmd)
|
||||
threadCreate(&cpyThread, copyfileCommitFS_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
else
|
||||
threadCreate(&cpyThread, copyfileCommit_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
|
||||
ui::progBar fileProg(fsize(from));
|
||||
threadStart(&cpyThread);
|
||||
while(!thr->fin)
|
||||
{
|
||||
fileProg.update(*thr->pos);
|
||||
gfxBeginFrame();
|
||||
fileProg.draw(from, "Copying File...");
|
||||
gfxEndFrame();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
delete thr;
|
||||
}
|
||||
|
||||
void copyDirToDir(const std::string& from, const std::string& to)
|
||||
{
|
||||
dirList list(from);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newFrom = from + list.getItem(i) + "/";
|
||||
std::string newTo = to + list.getItem(i);
|
||||
mkdir(newTo.c_str(), 0777);
|
||||
newTo += "/";
|
||||
|
||||
copyDirToDir(newFrom, newTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fullFrom = from + list.getItem(i);
|
||||
std::string fullTo = to + list.getItem(i);
|
||||
|
||||
if(hasFreeSpace(fullTo, fsize(fullFrom)))
|
||||
copyFile(fullFrom, fullTo);
|
||||
else
|
||||
ui::showMessage("*Error*", "Not enough free space to copy #%s#!", fullFrom.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev)
|
||||
{
|
||||
dirList list(from);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newFrom = from + list.getItem(i) + "/";
|
||||
std::string newTo = to + list.getItem(i);
|
||||
mkdir(newTo.c_str(), 0777);
|
||||
newTo += "/";
|
||||
|
||||
copyDirToDirCommit(newFrom, newTo, dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fullFrom = from + list.getItem(i);
|
||||
std::string fullTo = to + list.getItem(i);
|
||||
|
||||
if(hasFreeSpace(fullTo, fsize(fullFrom)))
|
||||
copyFileCommit(fullFrom, fullTo, dev);
|
||||
else
|
||||
ui::showMessage("*Error*", "Not enough free space to copy #%s#!", fullFrom.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void delfile(const std::string& path)
|
||||
{
|
||||
if(data::directFsCmd)
|
||||
fsremove(path.c_str());
|
||||
else
|
||||
remove(path.c_str());
|
||||
}
|
||||
|
||||
void delDir(const std::string& path)
|
||||
{
|
||||
dirList list(path);
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newPath = path + list.getItem(i) + "/";
|
||||
delDir(newPath);
|
||||
|
||||
std::string delPath = path + list.getItem(i);
|
||||
rmdir(delPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string delPath = path + list.getItem(i);
|
||||
std::remove(delPath.c_str());
|
||||
}
|
||||
}
|
||||
rmdir(path.c_str());
|
||||
}
|
||||
|
||||
bool dumpAllUserSaves(data::user& u)
|
||||
{
|
||||
for(unsigned i = 0; i < u.titles.size(); i++)
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
if(hidKeysHeld(CONTROLLER_P1_AUTO) & KEY_B)
|
||||
return false;
|
||||
|
||||
if(fs::mountSave(u, u.titles[i]))
|
||||
{
|
||||
u.titles[i].createDir();
|
||||
|
||||
//sdmc:/JKSV/[title]/[user] - [date]/
|
||||
std::string outPath = u.titles[i].getPath() + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC);
|
||||
mkdir(outPath.c_str(), 777);
|
||||
outPath += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::copyDirToDir(root, outPath);
|
||||
|
||||
fsdevUnmountDevice("sv");
|
||||
}
|
||||
}
|
||||
|
||||
return true;//?
|
||||
}
|
||||
|
||||
std::string getFileProps(const std::string& _path)
|
||||
{
|
||||
std::string ret = "";
|
||||
|
||||
FILE *get = fopen(_path.c_str(), "rb");
|
||||
if(get != NULL)
|
||||
{
|
||||
//Size
|
||||
fseek(get, 0, SEEK_END);
|
||||
unsigned fileSize = ftell(get);
|
||||
fseek(get, 0, SEEK_SET);
|
||||
|
||||
fclose(get);
|
||||
|
||||
//Probably add more later
|
||||
|
||||
char tmp[256];
|
||||
std::sprintf(tmp, "Path: \"%s\"\nSize: %u", _path.c_str(), fileSize);
|
||||
|
||||
ret = tmp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void getDirProps(const std::string& _path, uint32_t& dirCount, uint32_t& fileCount, uint64_t& totalSize)
|
||||
{
|
||||
fs::dirList list(_path);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
dirCount++;
|
||||
std::string newPath = _path + list.getItem(i) + "/";
|
||||
uint32_t dirAdd = 0, fileAdd = 0;
|
||||
uint64_t sizeAdd = 0;
|
||||
|
||||
getDirProps(newPath, dirAdd, fileAdd, sizeAdd);
|
||||
dirCount += dirAdd;
|
||||
fileCount += fileAdd;
|
||||
totalSize += sizeAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileCount++;
|
||||
std::string filePath = _path + list.getItem(i);
|
||||
|
||||
FILE *gSize = fopen(filePath.c_str(), "rb");
|
||||
fseek(gSize, 0, SEEK_END);
|
||||
size_t fSize = ftell(gSize);
|
||||
fclose(gSize);
|
||||
|
||||
totalSize += fSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool fileExists(const std::string& path)
|
||||
{
|
||||
FILE *test = fopen(path.c_str(), "rb");
|
||||
if(test != NULL)
|
||||
{
|
||||
fclose(test);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t fsize(const std::string& _f)
|
||||
{
|
||||
size_t ret = 0;
|
||||
FILE *get = fopen(_f.c_str(), "rb");
|
||||
if(get != NULL)
|
||||
{
|
||||
fseek(get, 0, SEEK_END);
|
||||
ret = ftell(get);
|
||||
fseek(get, 0, SEEK_SET);
|
||||
}
|
||||
fclose(get);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool hasFreeSpace(const std::string& _f, int needed)
|
||||
{
|
||||
s64 free = 0;
|
||||
//grab device from _f
|
||||
size_t endDevPos = _f.find(':', 0);
|
||||
std::string dev;
|
||||
dev.assign(_f.begin(), _f.begin() + endDevPos);
|
||||
fsFsGetFreeSpace(fsdevGetDeviceFileSystem(dev.c_str()), "/", &free);
|
||||
|
||||
return free > needed;
|
||||
}
|
||||
|
||||
std::string getWorkDir() { return wd; }
|
||||
|
||||
bool isDir(const std::string& _path)
|
||||
{
|
||||
struct stat s;
|
||||
return stat(_path.c_str(), &s) == 0 && S_ISDIR(s.st_mode);
|
||||
}
|
||||
|
||||
void logOpen()
|
||||
{
|
||||
std::string logPath = wd + "log.txt";
|
||||
remove(logPath.c_str());
|
||||
log = fsfopen(logPath.c_str(), FsOpenMode_Write);
|
||||
}
|
||||
|
||||
void logWrite(const char *fmt, ...)
|
||||
if(fs::fileExists("sdmc:/switch/jksv_dir.txt"))
|
||||
{
|
||||
char tmp[256];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
fsfwrite(tmp, 1, strlen(tmp), log);
|
||||
FILE *getDir = fopen("sdmc:/switch/jksv_dir.txt", "r");
|
||||
fgets(tmp, 256, getDir);
|
||||
fclose(getDir);
|
||||
wd = tmp;
|
||||
util::stripChar('\n', wd);
|
||||
util::stripChar('\r', wd);
|
||||
mkdirRec(wd);
|
||||
}
|
||||
|
||||
void logClose()
|
||||
else
|
||||
{
|
||||
fsfclose(log);
|
||||
mkdir("sdmc:/JKSV", 777);
|
||||
wd = "sdmc:/JKSV/";
|
||||
}
|
||||
fs::logOpen();
|
||||
}
|
||||
|
||||
void fs::exit()
|
||||
{
|
||||
fs::logClose();
|
||||
}
|
||||
|
||||
bool fs::mountSave(data::user& usr, data::titledata& open)
|
||||
{
|
||||
Result svOpen;
|
||||
FsFileSystem sv;
|
||||
|
||||
switch(open.getType())
|
||||
{
|
||||
case FsSaveDataType_System:
|
||||
svOpen = fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, open.getID(), usr.getUID128() == 1 ? (AccountUid) { 0 } : usr.getUID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Account:
|
||||
svOpen = fsOpen_SaveData(&sv, open.getID(), usr.getUID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
svOpen = fsOpen_BcatSaveData(&sv, open.getID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
svOpen = fsOpen_DeviceSaveData(&sv, open.getID());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Temporary:
|
||||
svOpen = fsOpen_TemporaryStorage(&sv);
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
svOpen = fsOpen_CacheStorage(&sv, open.getID(), open.getSaveIndex());
|
||||
break;
|
||||
|
||||
case FsSaveDataType_SystemBcat:
|
||||
svOpen = fsOpen_SystemBcatSaveData(&sv, open.getID());
|
||||
break;
|
||||
|
||||
default:
|
||||
svOpen = 1;
|
||||
break;
|
||||
}
|
||||
return R_SUCCEEDED(svOpen) && fsdevMountDevice("sv", sv) != -1;
|
||||
}
|
||||
|
||||
fs::dirItem::dirItem(const std::string& pathTo, const std::string& sItem)
|
||||
{
|
||||
itm = sItem;
|
||||
|
||||
std::string fullPath = pathTo + sItem;
|
||||
struct stat s;
|
||||
if(stat(fullPath.c_str(), &s) == 0 && S_ISDIR(s.st_mode))
|
||||
dir = true;
|
||||
}
|
||||
|
||||
fs::dirList::dirList(const std::string& _path)
|
||||
{
|
||||
path = _path;
|
||||
d = opendir(path.c_str());
|
||||
|
||||
while((ent = readdir(d)))
|
||||
item.push_back(dirItem(path, ent->d_name));
|
||||
|
||||
closedir(d);
|
||||
|
||||
std::sort(item.begin(), item.end(), sortDirList);
|
||||
}
|
||||
|
||||
void fs::dirList::reassign(const std::string& _path)
|
||||
{
|
||||
path = _path;
|
||||
|
||||
d = opendir(path.c_str());
|
||||
|
||||
item.clear();
|
||||
|
||||
while((ent = readdir(d)))
|
||||
item.push_back(dirItem(path, ent->d_name));
|
||||
|
||||
closedir(d);
|
||||
|
||||
std::sort(item.begin(), item.end(), sortDirList);
|
||||
}
|
||||
|
||||
void fs::dirList::rescan()
|
||||
{
|
||||
item.clear();
|
||||
d = opendir(path.c_str());
|
||||
|
||||
while((ent = readdir(d)))
|
||||
item.push_back(dirItem(path, ent->d_name));
|
||||
|
||||
closedir(d);
|
||||
|
||||
std::sort(item.begin(), item.end(), sortDirList);
|
||||
}
|
||||
|
||||
fs::dataFile::dataFile(const std::string& _path)
|
||||
{
|
||||
f = fopen(_path.c_str(), "r");
|
||||
if(f != NULL)
|
||||
opened = true;
|
||||
}
|
||||
|
||||
fs::dataFile::~dataFile()
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
bool fs::dataFile::readNextLine(bool proc)
|
||||
{
|
||||
bool ret = false;
|
||||
char tmp[1024];
|
||||
while(fgets(tmp, 1024, f))
|
||||
{
|
||||
if(tmp[0] != '#' && tmp[0] != '\n')
|
||||
{
|
||||
line = tmp;
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
util::stripChar('\n', line);
|
||||
util::stripChar('\r', line);
|
||||
if(proc)
|
||||
procLine();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fs::dataFile::procLine()
|
||||
{
|
||||
if((lPos = line.find_first_of('(')) != line.npos || (lPos = line.find_first_of('=')) != line.npos)
|
||||
name.assign(line.begin(), line.begin() + lPos);
|
||||
else
|
||||
name = "NULL";
|
||||
util::stripChar(' ', name);
|
||||
++lPos;
|
||||
}
|
||||
|
||||
std::string fs::dataFile::getNextValueStr()
|
||||
{
|
||||
//Skip all spaces until we hit actual text
|
||||
size_t pos1 = line.find_first_not_of(' ', lPos);
|
||||
//Set lPos to end of string we want. This should just set lPos to the end of the line if it fails, which is ok
|
||||
lPos = line.find_first_of(",;\n", pos1);
|
||||
return std::string(line.substr(pos1, lPos++));
|
||||
}
|
||||
|
||||
int fs::dataFile::getNextValueInt()
|
||||
{
|
||||
return strtol(getNextValueStr().c_str(), 0, 10);
|
||||
}
|
||||
|
||||
void fs::copyFile(const std::string& from, const std::string& to)
|
||||
{
|
||||
Thread cpyThread;
|
||||
uint64_t gProg = 0;
|
||||
copyArgs *thr = copyArgsCreate(from, to, "", &gProg);
|
||||
if(data::directFsCmd)
|
||||
threadCreate(&cpyThread, copyfileFS_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
else
|
||||
threadCreate(&cpyThread, copyfile_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
|
||||
ui::progBar fileProg(fsize(from));
|
||||
threadStart(&cpyThread);
|
||||
while(!thr->fin)
|
||||
{
|
||||
fileProg.update(*thr->pos);
|
||||
gfxBeginFrame();
|
||||
fileProg.draw(from, "Copying File...");
|
||||
gfxEndFrame();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
delete thr;
|
||||
}
|
||||
|
||||
void fs::copyFileCommit(const std::string& from, const std::string& to, const std::string& dev)
|
||||
{
|
||||
Thread cpyThread;
|
||||
uint64_t gProg = 0;
|
||||
copyArgs *thr = copyArgsCreate(from, to, dev, &gProg);
|
||||
if(data::directFsCmd)
|
||||
threadCreate(&cpyThread, copyfileCommitFS_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
else
|
||||
threadCreate(&cpyThread, copyfileCommit_t, thr, NULL, 0x4000, 0x2B, 1);
|
||||
|
||||
ui::progBar fileProg(fsize(from));
|
||||
threadStart(&cpyThread);
|
||||
while(!thr->fin)
|
||||
{
|
||||
fileProg.update(*thr->pos);
|
||||
gfxBeginFrame();
|
||||
fileProg.draw(from, "Copying File...");
|
||||
gfxEndFrame();
|
||||
}
|
||||
threadClose(&cpyThread);
|
||||
delete thr;
|
||||
}
|
||||
|
||||
void fs::copyDirToDir(const std::string& from, const std::string& to)
|
||||
{
|
||||
dirList list(from);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newFrom = from + list.getItem(i) + "/";
|
||||
std::string newTo = to + list.getItem(i);
|
||||
mkdir(newTo.c_str(), 0777);
|
||||
newTo += "/";
|
||||
|
||||
copyDirToDir(newFrom, newTo);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fullFrom = from + list.getItem(i);
|
||||
std::string fullTo = to + list.getItem(i);
|
||||
|
||||
if(hasFreeSpace(fullTo, fsize(fullFrom)))
|
||||
copyFile(fullFrom, fullTo);
|
||||
else
|
||||
ui::showMessage("*Error*", "Not enough free space to copy #%s#!", fullFrom.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fs::copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev)
|
||||
{
|
||||
dirList list(from);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newFrom = from + list.getItem(i) + "/";
|
||||
std::string newTo = to + list.getItem(i);
|
||||
mkdir(newTo.c_str(), 0777);
|
||||
newTo += "/";
|
||||
|
||||
copyDirToDirCommit(newFrom, newTo, dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fullFrom = from + list.getItem(i);
|
||||
std::string fullTo = to + list.getItem(i);
|
||||
|
||||
if(hasFreeSpace(fullTo, fsize(fullFrom)))
|
||||
copyFileCommit(fullFrom, fullTo, dev);
|
||||
else
|
||||
ui::showMessage("*Error*", "Not enough free space to copy #%s#!", fullFrom.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fs::delfile(const std::string& path)
|
||||
{
|
||||
if(data::directFsCmd)
|
||||
fsremove(path.c_str());
|
||||
else
|
||||
remove(path.c_str());
|
||||
}
|
||||
|
||||
void fs::delDir(const std::string& path)
|
||||
{
|
||||
dirList list(path);
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newPath = path + list.getItem(i) + "/";
|
||||
delDir(newPath);
|
||||
|
||||
std::string delPath = path + list.getItem(i);
|
||||
rmdir(delPath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string delPath = path + list.getItem(i);
|
||||
std::remove(delPath.c_str());
|
||||
}
|
||||
}
|
||||
rmdir(path.c_str());
|
||||
}
|
||||
|
||||
bool fs::dumpAllUserSaves(data::user& u)
|
||||
{
|
||||
for(unsigned i = 0; i < u.titles.size(); i++)
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
if(hidKeysHeld(CONTROLLER_P1_AUTO) & KEY_B)
|
||||
return false;
|
||||
|
||||
if(fs::mountSave(u, u.titles[i]))
|
||||
{
|
||||
u.titles[i].createDir();
|
||||
|
||||
//sdmc:/JKSV/[title]/[user] - [date]/
|
||||
std::string outPath = u.titles[i].getPath() + u.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC);
|
||||
mkdir(outPath.c_str(), 777);
|
||||
outPath += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::copyDirToDir(root, outPath);
|
||||
|
||||
fsdevUnmountDevice("sv");
|
||||
}
|
||||
}
|
||||
|
||||
return true;//?
|
||||
}
|
||||
|
||||
std::string fs::getFileProps(const std::string& _path)
|
||||
{
|
||||
std::string ret = "";
|
||||
|
||||
FILE *get = fopen(_path.c_str(), "rb");
|
||||
if(get != NULL)
|
||||
{
|
||||
//Size
|
||||
fseek(get, 0, SEEK_END);
|
||||
unsigned fileSize = ftell(get);
|
||||
fseek(get, 0, SEEK_SET);
|
||||
|
||||
fclose(get);
|
||||
|
||||
//Probably add more later
|
||||
|
||||
char tmp[256];
|
||||
std::sprintf(tmp, "Path: \"%s\"\nSize: %u", _path.c_str(), fileSize);
|
||||
|
||||
ret = tmp;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fs::getDirProps(const std::string& _path, uint32_t& dirCount, uint32_t& fileCount, uint64_t& totalSize)
|
||||
{
|
||||
fs::dirList list(_path);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
dirCount++;
|
||||
std::string newPath = _path + list.getItem(i) + "/";
|
||||
uint32_t dirAdd = 0, fileAdd = 0;
|
||||
uint64_t sizeAdd = 0;
|
||||
|
||||
getDirProps(newPath, dirAdd, fileAdd, sizeAdd);
|
||||
dirCount += dirAdd;
|
||||
fileCount += fileAdd;
|
||||
totalSize += sizeAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
fileCount++;
|
||||
std::string filePath = _path + list.getItem(i);
|
||||
|
||||
FILE *gSize = fopen(filePath.c_str(), "rb");
|
||||
fseek(gSize, 0, SEEK_END);
|
||||
size_t fSize = ftell(gSize);
|
||||
fclose(gSize);
|
||||
|
||||
totalSize += fSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool fs::fileExists(const std::string& path)
|
||||
{
|
||||
FILE *test = fopen(path.c_str(), "rb");
|
||||
if(test != NULL)
|
||||
{
|
||||
fclose(test);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t fs::fsize(const std::string& _f)
|
||||
{
|
||||
size_t ret = 0;
|
||||
FILE *get = fopen(_f.c_str(), "rb");
|
||||
if(get != NULL)
|
||||
{
|
||||
fseek(get, 0, SEEK_END);
|
||||
ret = ftell(get);
|
||||
fseek(get, 0, SEEK_SET);
|
||||
}
|
||||
fclose(get);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool fs::hasFreeSpace(const std::string& _f, int needed)
|
||||
{
|
||||
s64 free = 0;
|
||||
//grab device from _f
|
||||
size_t endDevPos = _f.find(':', 0);
|
||||
std::string dev;
|
||||
dev.assign(_f.begin(), _f.begin() + endDevPos);
|
||||
fsFsGetFreeSpace(fsdevGetDeviceFileSystem(dev.c_str()), "/", &free);
|
||||
|
||||
return free > needed;
|
||||
}
|
||||
|
||||
std::string fs::getWorkDir() { return wd; }
|
||||
|
||||
bool fs::isDir(const std::string& _path)
|
||||
{
|
||||
struct stat s;
|
||||
return stat(_path.c_str(), &s) == 0 && S_ISDIR(s.st_mode);
|
||||
}
|
||||
|
||||
void fs::logOpen()
|
||||
{
|
||||
std::string logPath = wd + "log.txt";
|
||||
remove(logPath.c_str());
|
||||
log = fsfopen(logPath.c_str(), FsOpenMode_Write);
|
||||
}
|
||||
|
||||
void fs::logWrite(const char *fmt, ...)
|
||||
{
|
||||
char tmp[256];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
fsfwrite(tmp, 1, strlen(tmp), log);
|
||||
}
|
||||
|
||||
void fs::logClose()
|
||||
{
|
||||
fsfclose(log);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include "fsfile.h"
|
||||
|
||||
static char *getDeviceFromPath(char *dev, size_t _max, const char *path)
|
||||
char *getDeviceFromPath(char *dev, size_t _max, const char *path)
|
||||
{
|
||||
memset(dev, 0, _max);
|
||||
char *c = strchr(path, ':');
|
||||
|
|
@ -18,7 +18,7 @@ static char *getDeviceFromPath(char *dev, size_t _max, const char *path)
|
|||
return dev;
|
||||
}
|
||||
|
||||
static char *getFilePath(char *pathOut, size_t _max, const char *path)
|
||||
char *getFilePath(char *pathOut, size_t _max, const char *path)
|
||||
{
|
||||
memset(pathOut, 0, _max);
|
||||
char *c = strchr(path, '/');
|
||||
|
|
|
|||
62
src/gfx.c
62
src/gfx.c
|
|
@ -188,7 +188,6 @@ void drawText(const char *str, tex *target, const font *f, int x, int y, int sz,
|
|||
continue;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
case '#':
|
||||
if(clrGetColor(textClr) == 0xFFEE9900)
|
||||
textClr = c;
|
||||
|
|
@ -204,6 +203,22 @@ void drawText(const char *str, tex *target, const font *f, int x, int y, int sz,
|
|||
textClr = clrCreateU32(0xFF0000FF);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if(clrGetColor(textClr) == 0xFF00FCF8)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FCF8);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if(clrGetColor(textClr) == 0xFF00FF00)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FF00);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
FT_GlyphSlot slot = loadGlyph(tmpChr, f, FT_LOAD_RENDER);
|
||||
|
|
@ -259,7 +274,6 @@ void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int
|
|||
continue;
|
||||
break;
|
||||
|
||||
case '"':
|
||||
case '#':
|
||||
if(clrGetColor(textClr) == 0xFFEE9900)
|
||||
textClr = c;
|
||||
|
|
@ -275,6 +289,22 @@ void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int
|
|||
textClr = clrCreateU32(0xFF0000FF);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '<':
|
||||
if(clrGetColor(textClr) == 0xFF00FCF8)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FCF8);
|
||||
continue;
|
||||
break;
|
||||
|
||||
case '>':
|
||||
if(clrGetColor(textClr) == 0xFF00FF00)
|
||||
textClr = c;
|
||||
else
|
||||
textClr = clrCreateU32(0xFF00FF00);
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
FT_GlyphSlot slot = loadGlyph(tmpChr, f, FT_LOAD_RENDER);
|
||||
|
|
@ -503,23 +533,23 @@ tex *texLoadJPEGMem(const uint8_t *jpegData, size_t jpegSize)
|
|||
jpeg_start_decompress(&jpegInfo);
|
||||
|
||||
JSAMPARRAY row = malloc(sizeof(JSAMPROW));
|
||||
for(unsigned i = 0; i < ret->height; i++)
|
||||
row[0] = malloc(sizeof(JSAMPLE) * ret->width * 3);
|
||||
for(unsigned i = 0; i < ret->height; i++)
|
||||
row[0] = malloc(sizeof(JSAMPLE) * ret->width * 3);
|
||||
|
||||
uint32_t *dataPtr = &ret->data[0];
|
||||
for(int y = 0; y < ret->height; y++)
|
||||
{
|
||||
jpeg_read_scanlines(&jpegInfo, row, 1);
|
||||
uint8_t *jpegPtr = row[0];
|
||||
for(int x = 0; x < ret->width; x++, jpegPtr += 3)
|
||||
*dataPtr++ = (0xFF << 24 | jpegPtr[2] << 16 | jpegPtr[1] << 8 | jpegPtr[0]);
|
||||
}
|
||||
uint32_t *dataPtr = &ret->data[0];
|
||||
for(int y = 0; y < ret->height; y++)
|
||||
{
|
||||
jpeg_read_scanlines(&jpegInfo, row, 1);
|
||||
uint8_t *jpegPtr = row[0];
|
||||
for(int x = 0; x < ret->width; x++, jpegPtr += 3)
|
||||
*dataPtr++ = (0xFF << 24 | jpegPtr[2] << 16 | jpegPtr[1] << 8 | jpegPtr[0]);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&jpegInfo);
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
jpeg_finish_decompress(&jpegInfo);
|
||||
jpeg_destroy_decompress(&jpegInfo);
|
||||
|
||||
free(row[0]);
|
||||
free(row);
|
||||
free(row[0]);
|
||||
free(row);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,16 +39,12 @@ extern "C"
|
|||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
//Max cpu to speed up boot. Doesn't take long.
|
||||
util::setCPU(1785000000);
|
||||
fs::init();
|
||||
graphicsInit(1280, 720);
|
||||
ui::initTheme();
|
||||
ui::showLoadScreen();
|
||||
data::init();
|
||||
ui::init();
|
||||
//Reset cpu
|
||||
util::setCPU(data::ovrClk ? 1224000000 : 1020000000);
|
||||
|
||||
while(appletMainLoop())
|
||||
{
|
||||
|
|
@ -65,10 +61,6 @@ int main(int argc, const char *argv[])
|
|||
gfxEndFrame();
|
||||
}
|
||||
|
||||
//reset cpu on exit
|
||||
if(data::ovrClk)
|
||||
util::setCPU(1020000000);
|
||||
|
||||
ui::exit();
|
||||
data::exit();
|
||||
graphicsExit();
|
||||
|
|
|
|||
786
src/ui.cpp
786
src/ui.cpp
|
|
@ -10,24 +10,74 @@
|
|||
#include "util.h"
|
||||
#include "file.h"
|
||||
|
||||
#define VER_STRING "v. 05.20.2020"
|
||||
#define VER_STRING "v. 05.22.2020"
|
||||
|
||||
//text mode
|
||||
bool ui::textMode = false;
|
||||
|
||||
//Current menu state
|
||||
int ui::mstate = USR_SEL, ui::prevState = USR_SEL;
|
||||
|
||||
//Theme id
|
||||
ColorSetId ui::thmID;
|
||||
|
||||
//Info printed on folder menu
|
||||
std::string ui::folderMenuInfo;
|
||||
|
||||
//UI colors
|
||||
clr ui::clearClr, ui::txtCont, ui::txtDiag, ui::rectLt, ui::rectSh, ui::tboxClr, divClr;
|
||||
|
||||
//textbox pieces
|
||||
//I was going to flip them when I draw them, but then laziness kicked in.
|
||||
tex *ui::cornerTopLeft, *ui::cornerTopRight, *ui::cornerBottomLeft, *ui::cornerBottomRight;
|
||||
|
||||
//Progress bar covers + dialog box predrawn
|
||||
tex *ui::progCovLeft, *ui::progCovRight, *ui::diaBox;
|
||||
|
||||
//Menu box pieces
|
||||
tex *mnuTopLeft, *mnuTopRight, *mnuBotLeft, *mnuBotRight;
|
||||
|
||||
//Select box + top left icon
|
||||
tex *ui::sideBar;
|
||||
|
||||
//Shared font
|
||||
font *ui::shared;
|
||||
|
||||
//Don't waste time drawing top and bottom over and over
|
||||
//guide graphics are to save cpu drawing that over and over with alpha
|
||||
static tex *top, *bot, *usrGuide, *ttlGuide, *fldrGuide, *optGuide;
|
||||
|
||||
//Ui text strings
|
||||
std::string author, ui::userHelp, ui::titleHelp, ui::folderHelp, ui::optHelp, \
|
||||
ui::confBlackList, ui::confOverwrite, ui::confRestore, ui::confDel, ui::confCopy, \
|
||||
ui::confEraseNand, ui::confEraseFolder, ui::yt, ui::nt;
|
||||
//UI text strings
|
||||
//Freedom English stored by default
|
||||
std::string author;
|
||||
std::string ui::userHelp = "[A] Select [Y] Dump All [X] UI Mode [-] Options [ZR] Extras";
|
||||
std::string ui::titleHelp = "[A] Select [L][R] Change User [Y] Dump All [X] Favorite [-] BlackList [ZR] Erase [B] Back";
|
||||
std::string ui::folderHelp = "[-] File Mode [L][R] Auto [A] Backup [Y] Restore [X] Delete Folder [ZR] Erase [B] Back";
|
||||
std::string ui::optHelp = "[A] Toggle [B] Back";
|
||||
std::string ui::yt = "Yes [A]", ui::nt = "No [B]";
|
||||
std::string ui::on = ">On>", ui::off = "Off";
|
||||
std::string ui::confBlacklist = "Are you sure you want to add #%s# to your blacklist?";
|
||||
std::string ui::confOverwrite = "Are you sure you want to overwrite #%s#?";
|
||||
std::string ui::confRestore = "Are you sure you want to restore #%s#?";
|
||||
std::string ui::confDel = "Are you sure you want to delete #%s#? *This is permanent*!";
|
||||
std::string ui::confCopy = "Are you sure you want to copy #%s# to #%s#?";
|
||||
std::string ui::confEraseNand = "*WARNING*: This *will* erase the save data for #%s# *from your system*. This is the same as deleting it from #Data Management#! Are you sure you want to continue?";
|
||||
std::string ui::confEraseFolder = "*WARNING*: This *will* delete the current save data for #%s# *from your system*! Are you sure you want to continue?";
|
||||
std::string ui::advMenuStr[6] = { "Copy to ", "Delete", "Rename", "Make Dir", "Properties", "Close" };
|
||||
std::string ui::exMenuStr[10] = { "SD to SD Browser", "BIS: PRODINFOF", "BIS: SAFE", "BIS: SYSTEM", "BIS: USER", "Remove Update", "Terminate Process", "Mount System Save", "Rescan Titles", "Mount Process RomFS" };
|
||||
std::string ui::optMenuStr[12] = { "Include Dev Sv: ", "AutoBackup: ", "Overclock: ", "Hold to Delete: ", "Hold to Restore: ", "Hold to Overwrite: ", "Force Mount: ", "Account Sys. Saves: ", "Write to Sys. Saves: ", "Text UI Mode: ", "Direct FS Cmd: ", "Skip User Select: " };
|
||||
|
||||
//X position of help texts. Calculated to make editing quicker/easier
|
||||
static unsigned userHelpX, titleHelpX, folderHelpX, optHelpX;
|
||||
|
||||
static void loadTrans()
|
||||
{
|
||||
bool transFile = fs::fileExists(fs::getWorkDir() + "trans.txt");
|
||||
if(!transFile && data::sysLang == SetLanguage_ENUS)
|
||||
return;//Don't bother loading from file. It serves as a translation guide
|
||||
|
||||
std::string file;
|
||||
if(fs::fileExists(fs::getWorkDir() + "trans.txt"))
|
||||
if(transFile)
|
||||
file = fs::getWorkDir() + "trans.txt";
|
||||
else
|
||||
{
|
||||
|
|
@ -41,372 +91,376 @@ static void loadTrans()
|
|||
}
|
||||
|
||||
fs::dataFile lang(file);
|
||||
author = lang.getNextLine();
|
||||
if(author == "NULL")
|
||||
author = "";
|
||||
|
||||
ui::userHelp = lang.getNextLine();
|
||||
ui::titleHelp = lang.getNextLine();
|
||||
ui::folderHelp = lang.getNextLine();
|
||||
ui::optHelp = lang.getNextLine();
|
||||
ui::yt = lang.getNextLine();
|
||||
ui::nt = lang.getNextLine();
|
||||
ui::confBlackList = lang.getNextLine();
|
||||
ui::confOverwrite = lang.getNextLine();
|
||||
ui::confRestore = lang.getNextLine();
|
||||
ui::confDel = lang.getNextLine();
|
||||
ui::confCopy = lang.getNextLine();
|
||||
ui::confEraseNand = lang.getNextLine();
|
||||
ui::confEraseFolder = lang.getNextLine();
|
||||
while(lang.readNextLine(true))
|
||||
{
|
||||
//Holy shit this'll be fun
|
||||
if(lang.getName() == "author")
|
||||
author = lang.getNextValueStr();
|
||||
else if(lang.getName() == "userHelp")
|
||||
ui::userHelp = lang.getNextValueStr();
|
||||
else if(lang.getName() == "titleHelp")
|
||||
ui::titleHelp = lang.getNextValueStr();
|
||||
else if(lang.getName() == "folderHelp")
|
||||
ui::folderHelp = lang.getNextValueStr();
|
||||
else if(lang.getName() == "optHelp")
|
||||
ui::optHelp = lang.getNextValueStr();
|
||||
else if(lang.getName() == "yt")
|
||||
ui::yt = lang.getNextValueStr();
|
||||
else if(lang.getName() == "nt")
|
||||
ui::nt = lang.getNextValueStr();
|
||||
else if(lang.getName() == "on")
|
||||
ui::on = lang.getNextValueStr();
|
||||
else if(lang.getName() == "off")
|
||||
ui::off = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmBlacklist")
|
||||
ui::confBlacklist = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmOverwrite")
|
||||
ui::confOverwrite = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmRestore")
|
||||
ui::confRestore = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmDelete")
|
||||
ui::confDel = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmCopy")
|
||||
ui::confCopy = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmEraseNand")
|
||||
ui::confEraseNand = lang.getNextValueStr();
|
||||
else if(lang.getName() == "confirmEraseFolder")
|
||||
ui::confEraseFolder = lang.getNextValueStr();
|
||||
else if(lang.getName() == "advMenu")
|
||||
{
|
||||
int ind = lang.getNextValueInt();
|
||||
ui::advMenuStr[ind] = lang.getNextValueStr();
|
||||
}
|
||||
else if(lang.getName() == "extMenu")
|
||||
{
|
||||
int ind = lang.getNextValueInt();
|
||||
ui::exMenuStr[ind] = lang.getNextValueStr();
|
||||
}
|
||||
else if(lang.getName() == "optMenu")
|
||||
{
|
||||
int ind = lang.getNextValueInt();
|
||||
ui::optMenuStr[ind] = lang.getNextValueStr();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ui
|
||||
void ui::initTheme()
|
||||
{
|
||||
//text mode
|
||||
bool textMode = false;
|
||||
if(fs::fileExists(fs::getWorkDir() + "font.ttf"))
|
||||
shared = fontLoadTTF(std::string(fs::getWorkDir() + "font.ttf").c_str());
|
||||
else
|
||||
shared = fontLoadSharedFonts();
|
||||
|
||||
//Current menu state
|
||||
int mstate = USR_SEL, prevState = USR_SEL;
|
||||
setsysGetColorSetId(&thmID);
|
||||
|
||||
//Theme id
|
||||
ColorSetId thmID;
|
||||
|
||||
//Info printed on folder menu
|
||||
std::string folderMenuInfo;
|
||||
|
||||
//UI colors
|
||||
clr clearClr, txtCont, txtDiag, rectLt, rectSh, tboxClr, divClr;
|
||||
|
||||
//textbox pieces
|
||||
//I was going to flip them when I draw them, but then laziness kicked in.
|
||||
tex *cornerTopLeft, *cornerTopRight, *cornerBottomLeft, *cornerBottomRight;
|
||||
tex *progCovLeft, *progCovRight, *diaBox;
|
||||
|
||||
//Menu box pieces
|
||||
tex *mnuTopLeft, *mnuTopRight, *mnuBotLeft, *mnuBotRight;
|
||||
|
||||
//Select box + top left icon
|
||||
tex *icn, *sideBar;
|
||||
|
||||
//Shared font
|
||||
font *shared;
|
||||
|
||||
void initTheme()
|
||||
switch(thmID)
|
||||
{
|
||||
if(fs::fileExists(fs::getWorkDir() + "font.ttf"))
|
||||
shared = fontLoadTTF(std::string(fs::getWorkDir() + "font.ttf").c_str());
|
||||
else
|
||||
shared = fontLoadSharedFonts();
|
||||
case ColorSetId_Light:
|
||||
clearClr = clrCreateU32(0xFFEBEBEB);
|
||||
txtCont = clrCreateU32(0xFF000000);
|
||||
txtDiag = clrCreateU32(0xFFFFFFFF);
|
||||
rectLt = clrCreateU32(0xFFDFDFDF);
|
||||
rectSh = clrCreateU32(0xFFCACACA);
|
||||
tboxClr = clrCreateU32(0xFF505050);
|
||||
divClr = clrCreateU32(0xFF000000);
|
||||
break;
|
||||
|
||||
setsysGetColorSetId(&thmID);
|
||||
|
||||
switch(thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
clearClr = clrCreateU32(0xFFEBEBEB);
|
||||
txtCont = clrCreateU32(0xFF000000);
|
||||
txtDiag = clrCreateU32(0xFFFFFFFF);
|
||||
rectLt = clrCreateU32(0xFFDFDFDF);
|
||||
rectSh = clrCreateU32(0xFFCACACA);
|
||||
tboxClr = clrCreateU32(0xFF505050);
|
||||
divClr = clrCreateU32(0xFF000000);
|
||||
break;
|
||||
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
//jic
|
||||
thmID = ColorSetId_Dark;
|
||||
clearClr = clrCreateU32(0xFF2D2D2D);
|
||||
txtCont = clrCreateU32(0xFFFFFFFF);
|
||||
txtDiag = clrCreateU32(0xFF000000);
|
||||
rectLt = clrCreateU32(0xFF505050);
|
||||
rectSh = clrCreateU32(0xFF202020);
|
||||
tboxClr = clrCreateU32(0xFFEBEBEB);
|
||||
divClr = clrCreateU32(0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
mnuTopLeft = texLoadPNGFile("romfs:/img/fb/menuTopLeft.png");
|
||||
mnuTopRight = texLoadPNGFile("romfs:/img/fb/menuTopRight.png");
|
||||
mnuBotLeft = texLoadPNGFile("romfs:/img/fb/menuBotLeft.png");
|
||||
mnuBotRight = texLoadPNGFile("romfs:/img/fb/menuBotRight.png");
|
||||
switch(ui::thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
//Dark corners
|
||||
cornerTopLeft = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerTopLeft.png");
|
||||
cornerTopRight = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerTopRight.png");
|
||||
cornerBottomLeft = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerBotLeft.png");
|
||||
cornerBottomRight = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerBotRight.png");
|
||||
progCovLeft = texLoadPNGFile("romfs:/img/tboxDrk/progBarCoverLeftDrk.png");
|
||||
progCovRight = texLoadPNGFile("romfs:/img/tboxDrk/progBarCoverRightDrk.png");
|
||||
|
||||
icn = texLoadPNGFile("romfs:/img/icn/icnDrk.png");
|
||||
sideBar = texLoadPNGFile("romfs:/img/fb/lLight.png");
|
||||
break;
|
||||
|
||||
default:
|
||||
//Light corners
|
||||
cornerTopLeft = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerTopLeft.png");
|
||||
cornerTopRight = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerTopRight.png");
|
||||
cornerBottomLeft = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerBotLeft.png");
|
||||
cornerBottomRight = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerBotRight.png");
|
||||
progCovLeft = texLoadPNGFile("romfs:/img/tboxLght/progBarCoverLeftLight.png");
|
||||
progCovRight = texLoadPNGFile("romfs:/img/tboxLght/progBarCoverRightLight.png");
|
||||
|
||||
icn = texLoadPNGFile("romfs:/img/icn/icnLght.png");
|
||||
sideBar = texLoadPNGFile("romfs:/img/fb/lDark.png");
|
||||
break;
|
||||
}
|
||||
|
||||
top = texCreate(1280, 88);
|
||||
bot = texCreate(1280, 72);
|
||||
diaBox = texCreate(640, 420);
|
||||
|
||||
if(ui::textMode && data::skipUser)
|
||||
{
|
||||
ui::textTitlePrep(data::curUser);
|
||||
mstate = TXT_TTL;
|
||||
}
|
||||
else if(ui::textMode)
|
||||
mstate = TXT_USR;
|
||||
else if(data::skipUser)
|
||||
mstate = TTL_SEL;
|
||||
|
||||
|
||||
loadTrans();
|
||||
textUserPrep();
|
||||
|
||||
//Setup top and bottom gfx
|
||||
texClearColor(top, clearClr);
|
||||
texDraw(icn, top, 66, 27);
|
||||
drawText("JKSV", top, shared, 130, 38, 24, ui::txtCont);
|
||||
drawRect(top, 30, 87, 1220, 1, ui::txtCont);
|
||||
|
||||
texClearColor(bot, clearClr);
|
||||
drawRect(bot, 30, 0, 1220, 1, ui::txtCont);
|
||||
drawText(VER_STRING, bot, shared, 8, author.empty() ? 56 : 38, 12, ui::txtCont);
|
||||
if(!author.empty())
|
||||
drawText(std::string("Translation: " + author).c_str(), bot, ui::shared, 8, 56, 12, ui::txtCont);
|
||||
|
||||
//Not needed anymore
|
||||
texDestroy(icn);
|
||||
|
||||
//Setup dialog box
|
||||
drawTextbox(diaBox, 0, 0, 640, 420);
|
||||
drawRect(diaBox, 0, 56, 640, 2, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFF6D6D6D) : clrCreateU32(0xFFCCCCCC));
|
||||
|
||||
util::replaceButtonsInString(ui::userHelp);
|
||||
util::replaceButtonsInString(ui::titleHelp);
|
||||
util::replaceButtonsInString(ui::folderHelp);
|
||||
util::replaceButtonsInString(ui::optHelp);
|
||||
util::replaceButtonsInString(ui::yt);
|
||||
util::replaceButtonsInString(ui::nt);
|
||||
|
||||
//Create graphics to hold guides
|
||||
usrGuide = texCreate(textGetWidth(userHelp.c_str(), ui::shared, 18), 28);
|
||||
ttlGuide = texCreate(textGetWidth(titleHelp.c_str(), ui::shared, 18), 28);
|
||||
fldrGuide = texCreate(textGetWidth(folderHelp.c_str(), ui::shared, 18), 28);
|
||||
optGuide = texCreate(textGetWidth(optHelp.c_str(), ui::shared, 18), 28);
|
||||
|
||||
//Clear with bg color
|
||||
texClearColor(usrGuide, ui::clearClr);
|
||||
texClearColor(ttlGuide, ui::clearClr);
|
||||
texClearColor(fldrGuide, ui::clearClr);
|
||||
texClearColor(optGuide, ui::clearClr);
|
||||
|
||||
//Draw text to them
|
||||
drawText(userHelp.c_str(), usrGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(titleHelp.c_str(), ttlGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(folderHelp.c_str(), fldrGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(optHelp.c_str(), optGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
|
||||
//Calculate x position of help text
|
||||
userHelpX = 1220 - usrGuide->width;
|
||||
titleHelpX = 1220 - ttlGuide->width;
|
||||
folderHelpX = 1220 - fldrGuide->width;
|
||||
optHelpX = 1220 - optGuide->width;
|
||||
|
||||
advCopyMenuPrep();
|
||||
ui::exMenuPrep();
|
||||
ui::optMenuInit();
|
||||
}
|
||||
|
||||
void exit()
|
||||
{
|
||||
texDestroy(cornerTopLeft);
|
||||
texDestroy(cornerTopRight);
|
||||
texDestroy(cornerBottomLeft);
|
||||
texDestroy(cornerBottomRight);
|
||||
texDestroy(progCovLeft);
|
||||
texDestroy(progCovRight);
|
||||
|
||||
texDestroy(mnuTopLeft);
|
||||
texDestroy(mnuTopRight);
|
||||
texDestroy(mnuBotLeft);
|
||||
texDestroy(mnuBotRight);
|
||||
|
||||
texDestroy(usrGuide);
|
||||
texDestroy(ttlGuide);
|
||||
texDestroy(fldrGuide);
|
||||
texDestroy(optGuide);
|
||||
|
||||
texDestroy(top);
|
||||
texDestroy(bot);
|
||||
texDestroy(diaBox);
|
||||
|
||||
fontDestroy(shared);
|
||||
}
|
||||
|
||||
void showLoadScreen()
|
||||
{
|
||||
tex *icn = texLoadJPEGFile("romfs:/icon.jpg");
|
||||
gfxBeginFrame();
|
||||
texClearColor(frameBuffer, clrCreateU32(0xFF2D2D2D));
|
||||
texDrawNoAlpha(icn, frameBuffer, 512, 232);
|
||||
drawText("Loading...", frameBuffer, ui::shared, 1100, 673, 16, clrCreateU32(0xFFFFFFFF));
|
||||
gfxEndFrame();
|
||||
texDestroy(icn);
|
||||
}
|
||||
|
||||
void drawUI()
|
||||
{
|
||||
texClearColor(frameBuffer, clearClr);
|
||||
texDrawNoAlpha(top, frameBuffer, 0, 0);
|
||||
texDrawNoAlpha(bot, frameBuffer, 0, 648);
|
||||
|
||||
switch(mstate)
|
||||
{
|
||||
case USR_SEL:
|
||||
texDrawNoAlpha(usrGuide, frameBuffer, userHelpX, 673);
|
||||
break;
|
||||
|
||||
case TTL_SEL:
|
||||
texDrawNoAlpha(ttlGuide, frameBuffer, titleHelpX, 673);
|
||||
break;
|
||||
|
||||
case FLD_SEL:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(fldrGuide, frameBuffer, folderHelpX, 673);
|
||||
break;
|
||||
|
||||
case TXT_USR:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(usrGuide, frameBuffer, userHelpX, 673);
|
||||
break;
|
||||
|
||||
case TXT_TTL:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(ttlGuide, frameBuffer, titleHelpX, 673);
|
||||
break;
|
||||
|
||||
case TXT_FLD:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(fldrGuide, frameBuffer, folderHelpX, 673);
|
||||
break;
|
||||
|
||||
case EX_MNU:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
break;
|
||||
|
||||
case OPT_MNU:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(optGuide, frameBuffer, optHelpX, 673);
|
||||
break;
|
||||
|
||||
case ADV_MDE:
|
||||
drawRect(frameBuffer, 640, 88, 1, 559, ui::txtCont);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void drawBoundBox(int x, int y, int w, int h, int clrSh)
|
||||
{
|
||||
clr rectClr = clrCreateRGBA(0x00, 0x88 + clrSh, 0xC5 + (clrSh / 2), 0xFF);
|
||||
|
||||
texSwapColors(mnuTopLeft, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuTopRight, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuBotLeft, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuBotRight, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
|
||||
switch(ui::thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
drawRect(frameBuffer, x + 4, y + 4, w - 8, h - 8, clrCreateU32(0xFFFDFDFD));
|
||||
break;
|
||||
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
drawRect(frameBuffer, x + 4, y + 4, w - 8, h - 8, clrCreateU32(0xFF212221));
|
||||
break;
|
||||
}
|
||||
|
||||
//top
|
||||
texDraw(mnuTopLeft, frameBuffer, x, y);
|
||||
drawRect(frameBuffer, x + 4, y, w - 8, 4, rectClr);
|
||||
texDraw(mnuTopRight, frameBuffer, (x + w) - 4, y);
|
||||
|
||||
//mid
|
||||
drawRect(frameBuffer, x, y + 4, 4, h - 8, rectClr);
|
||||
drawRect(frameBuffer, (x + w) - 4, y + 4, 4, h - 8, rectClr);
|
||||
|
||||
//bottom
|
||||
texDraw(mnuBotLeft, frameBuffer, x, (y + h) - 4);
|
||||
drawRect(frameBuffer, x + 4, (y + h) - 4, w - 8, 4, rectClr);
|
||||
texDraw(mnuBotRight, frameBuffer, (x + w) - 4, (y + h) - 4);
|
||||
|
||||
texSwapColors(mnuTopLeft, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuTopRight, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuBotLeft, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuBotRight, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
}
|
||||
|
||||
void runApp(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
//Draw first. Shouldn't, but it simplifies the showX functions
|
||||
drawUI();
|
||||
|
||||
switch(mstate)
|
||||
{
|
||||
case USR_SEL:
|
||||
updateUserMenu(down, held);
|
||||
break;
|
||||
|
||||
case TTL_SEL:
|
||||
updateTitleMenu(down, held);
|
||||
break;
|
||||
|
||||
case FLD_SEL:
|
||||
updateFolderMenu(down, held);
|
||||
break;
|
||||
|
||||
case ADV_MDE:
|
||||
updateAdvMode(down, held);
|
||||
break;
|
||||
|
||||
case TXT_USR:
|
||||
textUserMenuUpdate(down, held);
|
||||
break;
|
||||
|
||||
case TXT_TTL:
|
||||
textTitleMenuUpdate(down, held);
|
||||
break;
|
||||
|
||||
case TXT_FLD:
|
||||
textFolderMenuUpdate(down, held);
|
||||
break;
|
||||
|
||||
case EX_MNU:
|
||||
updateExMenu(down, held);
|
||||
break;
|
||||
|
||||
case OPT_MNU:
|
||||
updateOptMenu(down, held);
|
||||
break;
|
||||
}
|
||||
drawPopup(down);
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
//jic
|
||||
thmID = ColorSetId_Dark;
|
||||
clearClr = clrCreateU32(0xFF2D2D2D);
|
||||
txtCont = clrCreateU32(0xFFFFFFFF);
|
||||
txtDiag = clrCreateU32(0xFF000000);
|
||||
rectLt = clrCreateU32(0xFF505050);
|
||||
rectSh = clrCreateU32(0xFF202020);
|
||||
tboxClr = clrCreateU32(0xFFEBEBEB);
|
||||
divClr = clrCreateU32(0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ui::init()
|
||||
{
|
||||
tex *icn;
|
||||
mnuTopLeft = texLoadPNGFile("romfs:/img/fb/menuTopLeft.png");
|
||||
mnuTopRight = texLoadPNGFile("romfs:/img/fb/menuTopRight.png");
|
||||
mnuBotLeft = texLoadPNGFile("romfs:/img/fb/menuBotLeft.png");
|
||||
mnuBotRight = texLoadPNGFile("romfs:/img/fb/menuBotRight.png");
|
||||
switch(ui::thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
//Dark corners
|
||||
cornerTopLeft = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerTopLeft.png");
|
||||
cornerTopRight = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerTopRight.png");
|
||||
cornerBottomLeft = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerBotLeft.png");
|
||||
cornerBottomRight = texLoadPNGFile("romfs:/img/tboxDrk/tboxCornerBotRight.png");
|
||||
progCovLeft = texLoadPNGFile("romfs:/img/tboxDrk/progBarCoverLeftDrk.png");
|
||||
progCovRight = texLoadPNGFile("romfs:/img/tboxDrk/progBarCoverRightDrk.png");
|
||||
|
||||
icn = texLoadPNGFile("romfs:/img/icn/icnDrk.png");
|
||||
sideBar = texLoadPNGFile("romfs:/img/fb/lLight.png");
|
||||
break;
|
||||
|
||||
default:
|
||||
//Light corners
|
||||
cornerTopLeft = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerTopLeft.png");
|
||||
cornerTopRight = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerTopRight.png");
|
||||
cornerBottomLeft = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerBotLeft.png");
|
||||
cornerBottomRight = texLoadPNGFile("romfs:/img/tboxLght/tboxCornerBotRight.png");
|
||||
progCovLeft = texLoadPNGFile("romfs:/img/tboxLght/progBarCoverLeftLight.png");
|
||||
progCovRight = texLoadPNGFile("romfs:/img/tboxLght/progBarCoverRightLight.png");
|
||||
|
||||
icn = texLoadPNGFile("romfs:/img/icn/icnLght.png");
|
||||
sideBar = texLoadPNGFile("romfs:/img/fb/lDark.png");
|
||||
break;
|
||||
}
|
||||
|
||||
top = texCreate(1280, 88);
|
||||
bot = texCreate(1280, 72);
|
||||
diaBox = texCreate(640, 420);
|
||||
|
||||
if(ui::textMode && data::skipUser)
|
||||
{
|
||||
ui::textTitlePrep(data::curUser);
|
||||
mstate = TXT_TTL;
|
||||
}
|
||||
else if(ui::textMode)
|
||||
mstate = TXT_USR;
|
||||
else if(data::skipUser)
|
||||
mstate = TTL_SEL;
|
||||
|
||||
|
||||
loadTrans();
|
||||
textUserPrep();
|
||||
|
||||
//Replace the button [x] in strings that need it. Needs to be outside loadTrans so even defaults will get replaced
|
||||
util::replaceButtonsInString(ui::userHelp);
|
||||
util::replaceButtonsInString(ui::titleHelp);
|
||||
util::replaceButtonsInString(ui::folderHelp);
|
||||
util::replaceButtonsInString(ui::optHelp);
|
||||
util::replaceButtonsInString(ui::yt);
|
||||
util::replaceButtonsInString(ui::nt);
|
||||
|
||||
//Setup top and bottom gfx
|
||||
texClearColor(top, clearClr);
|
||||
texDraw(icn, top, 66, 27);
|
||||
drawText("JKSV", top, shared, 130, 38, 24, ui::txtCont);
|
||||
drawRect(top, 30, 87, 1220, 1, ui::txtCont);
|
||||
|
||||
texClearColor(bot, clearClr);
|
||||
drawRect(bot, 30, 0, 1220, 1, ui::txtCont);
|
||||
drawText(VER_STRING, bot, shared, 8, author == "NULL" ? 56 : 38, 12, ui::txtCont);
|
||||
if(author != "NULL")
|
||||
drawText(std::string("Translation: " + author).c_str(), bot, ui::shared, 8, 56, 12, ui::txtCont);
|
||||
|
||||
//Not needed anymore
|
||||
texDestroy(icn);
|
||||
|
||||
//Setup dialog box
|
||||
drawTextbox(diaBox, 0, 0, 640, 420);
|
||||
drawRect(diaBox, 0, 56, 640, 2, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFF6D6D6D) : clrCreateU32(0xFFCCCCCC));
|
||||
|
||||
//Create graphics to hold guides
|
||||
usrGuide = texCreate(textGetWidth(userHelp.c_str(), ui::shared, 18), 28);
|
||||
ttlGuide = texCreate(textGetWidth(titleHelp.c_str(), ui::shared, 18), 28);
|
||||
fldrGuide = texCreate(textGetWidth(folderHelp.c_str(), ui::shared, 18), 28);
|
||||
optGuide = texCreate(textGetWidth(optHelp.c_str(), ui::shared, 18), 28);
|
||||
|
||||
//Clear with bg color
|
||||
texClearColor(usrGuide, ui::clearClr);
|
||||
texClearColor(ttlGuide, ui::clearClr);
|
||||
texClearColor(fldrGuide, ui::clearClr);
|
||||
texClearColor(optGuide, ui::clearClr);
|
||||
|
||||
//Draw text to them
|
||||
drawText(userHelp.c_str(), usrGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(titleHelp.c_str(), ttlGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(folderHelp.c_str(), fldrGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
drawText(optHelp.c_str(), optGuide, ui::shared, 0, 3, 18, ui::txtCont);
|
||||
|
||||
//Calculate x position of help text
|
||||
userHelpX = 1220 - usrGuide->width;
|
||||
titleHelpX = 1220 - ttlGuide->width;
|
||||
folderHelpX = 1220 - fldrGuide->width;
|
||||
optHelpX = 1220 - optGuide->width;
|
||||
|
||||
advCopyMenuPrep();
|
||||
ui::exMenuPrep();
|
||||
ui::optMenuInit();
|
||||
}
|
||||
|
||||
void ui::exit()
|
||||
{
|
||||
texDestroy(cornerTopLeft);
|
||||
texDestroy(cornerTopRight);
|
||||
texDestroy(cornerBottomLeft);
|
||||
texDestroy(cornerBottomRight);
|
||||
texDestroy(progCovLeft);
|
||||
texDestroy(progCovRight);
|
||||
|
||||
texDestroy(mnuTopLeft);
|
||||
texDestroy(mnuTopRight);
|
||||
texDestroy(mnuBotLeft);
|
||||
texDestroy(mnuBotRight);
|
||||
|
||||
texDestroy(usrGuide);
|
||||
texDestroy(ttlGuide);
|
||||
texDestroy(fldrGuide);
|
||||
texDestroy(optGuide);
|
||||
|
||||
texDestroy(top);
|
||||
texDestroy(bot);
|
||||
texDestroy(diaBox);
|
||||
|
||||
fontDestroy(shared);
|
||||
}
|
||||
|
||||
void ui::showLoadScreen()
|
||||
{
|
||||
tex *icn = texLoadJPEGFile("romfs:/icon.jpg");
|
||||
gfxBeginFrame();
|
||||
texClearColor(frameBuffer, clrCreateU32(0xFF2D2D2D));
|
||||
texDrawNoAlpha(icn, frameBuffer, 512, 232);
|
||||
drawText("Loading...", frameBuffer, ui::shared, 1100, 673, 16, clrCreateU32(0xFFFFFFFF));
|
||||
gfxEndFrame();
|
||||
texDestroy(icn);
|
||||
}
|
||||
|
||||
void ui::drawUI()
|
||||
{
|
||||
texClearColor(frameBuffer, clearClr);
|
||||
texDrawNoAlpha(top, frameBuffer, 0, 0);
|
||||
texDrawNoAlpha(bot, frameBuffer, 0, 648);
|
||||
|
||||
switch(mstate)
|
||||
{
|
||||
case USR_SEL:
|
||||
texDrawNoAlpha(usrGuide, frameBuffer, userHelpX, 673);
|
||||
break;
|
||||
|
||||
case TTL_SEL:
|
||||
texDrawNoAlpha(ttlGuide, frameBuffer, titleHelpX, 673);
|
||||
break;
|
||||
|
||||
case FLD_SEL:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(fldrGuide, frameBuffer, folderHelpX, 673);
|
||||
break;
|
||||
|
||||
case TXT_USR:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(usrGuide, frameBuffer, userHelpX, 673);
|
||||
break;
|
||||
|
||||
case TXT_TTL:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(ttlGuide, frameBuffer, titleHelpX, 673);
|
||||
break;
|
||||
|
||||
case TXT_FLD:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(fldrGuide, frameBuffer, folderHelpX, 673);
|
||||
break;
|
||||
|
||||
case EX_MNU:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
break;
|
||||
|
||||
case OPT_MNU:
|
||||
texDrawNoAlpha(sideBar, frameBuffer, 0, 88);
|
||||
texDrawNoAlpha(optGuide, frameBuffer, optHelpX, 673);
|
||||
break;
|
||||
|
||||
case ADV_MDE:
|
||||
drawRect(frameBuffer, 640, 88, 1, 559, ui::txtCont);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ui::drawBoundBox(int x, int y, int w, int h, int clrSh)
|
||||
{
|
||||
clr rectClr = clrCreateRGBA(0x00, 0x88 + clrSh, 0xC5 + (clrSh / 2), 0xFF);
|
||||
|
||||
texSwapColors(mnuTopLeft, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuTopRight, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuBotLeft, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
texSwapColors(mnuBotRight, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF), rectClr);
|
||||
|
||||
switch(ui::thmID)
|
||||
{
|
||||
case ColorSetId_Light:
|
||||
drawRect(frameBuffer, x + 4, y + 4, w - 8, h - 8, clrCreateU32(0xFFFDFDFD));
|
||||
break;
|
||||
|
||||
default:
|
||||
case ColorSetId_Dark:
|
||||
drawRect(frameBuffer, x + 4, y + 4, w - 8, h - 8, clrCreateU32(0xFF212221));
|
||||
break;
|
||||
}
|
||||
|
||||
//top
|
||||
texDraw(mnuTopLeft, frameBuffer, x, y);
|
||||
drawRect(frameBuffer, x + 4, y, w - 8, 4, rectClr);
|
||||
texDraw(mnuTopRight, frameBuffer, (x + w) - 4, y);
|
||||
|
||||
//mid
|
||||
drawRect(frameBuffer, x, y + 4, 4, h - 8, rectClr);
|
||||
drawRect(frameBuffer, (x + w) - 4, y + 4, 4, h - 8, rectClr);
|
||||
|
||||
//bottom
|
||||
texDraw(mnuBotLeft, frameBuffer, x, (y + h) - 4);
|
||||
drawRect(frameBuffer, x + 4, (y + h) - 4, w - 8, 4, rectClr);
|
||||
texDraw(mnuBotRight, frameBuffer, (x + w) - 4, (y + h) - 4);
|
||||
|
||||
texSwapColors(mnuTopLeft, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuTopRight, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuBotLeft, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
texSwapColors(mnuBotRight, rectClr, clrCreateRGBA(0x00, 0x88, 0xC5, 0xFF));
|
||||
}
|
||||
|
||||
void ui::runApp(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
//Draw first. Shouldn't, but it simplifies the showX functions
|
||||
drawUI();
|
||||
|
||||
switch(mstate)
|
||||
{
|
||||
case USR_SEL:
|
||||
updateUserMenu(down, held);
|
||||
break;
|
||||
|
||||
case TTL_SEL:
|
||||
updateTitleMenu(down, held);
|
||||
break;
|
||||
|
||||
case FLD_SEL:
|
||||
updateFolderMenu(down, held);
|
||||
break;
|
||||
|
||||
case ADV_MDE:
|
||||
updateAdvMode(down, held);
|
||||
break;
|
||||
|
||||
case TXT_USR:
|
||||
textUserMenuUpdate(down, held);
|
||||
break;
|
||||
|
||||
case TXT_TTL:
|
||||
textTitleMenuUpdate(down, held);
|
||||
break;
|
||||
|
||||
case TXT_FLD:
|
||||
textFolderMenuUpdate(down, held);
|
||||
break;
|
||||
|
||||
case EX_MNU:
|
||||
updateExMenu(down, held);
|
||||
break;
|
||||
|
||||
case OPT_MNU:
|
||||
updateOptMenu(down, held);
|
||||
break;
|
||||
}
|
||||
drawPopup(down);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -341,189 +341,184 @@ void performCopyMenuOps()
|
|||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
|
||||
namespace ui
|
||||
|
||||
void ui::advCopyMenuPrep()
|
||||
{
|
||||
void advCopyMenuPrep()
|
||||
for(unsigned i = 0; i < 6; i++)
|
||||
copyMenu.addOpt(ui::advMenuStr[i]);
|
||||
}
|
||||
|
||||
void ui::advModePrep(const std::string& svDev, bool commitOnWrite)
|
||||
{
|
||||
commit = commitOnWrite;
|
||||
saveMenu.setParams(30, 98, 602);
|
||||
sdMenu.setParams(648, 98, 602);
|
||||
copyMenu.setParams(472, 278, 304);
|
||||
|
||||
savePath = svDev, dev = svDev;
|
||||
sdPath = "sdmc:/";
|
||||
|
||||
saveList.reassign(savePath);
|
||||
sdList.reassign(sdPath);
|
||||
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
|
||||
advMenuCtrl = 0;
|
||||
}
|
||||
|
||||
void ui::updateAdvMode(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
//0 = save; 1 = sd; 2 = cpy
|
||||
switch(advMenuCtrl)
|
||||
{
|
||||
copyMenu.addOpt("Copy From");
|
||||
copyMenu.addOpt("Delete");
|
||||
copyMenu.addOpt("Rename");
|
||||
copyMenu.addOpt("Make Dir");
|
||||
copyMenu.addOpt("Properties");
|
||||
copyMenu.addOpt("Back");
|
||||
case 0:
|
||||
saveMenu.handleInput(down, held);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
sdMenu.handleInput(down, held);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
copyMenu.handleInput(down, held);
|
||||
break;
|
||||
}
|
||||
|
||||
void advModePrep(const std::string& svDev, bool commitOnWrite)
|
||||
saveMenu.draw(ui::txtCont);
|
||||
sdMenu.draw(ui::txtCont);
|
||||
|
||||
drawTextWrap(savePath.c_str(), frameBuffer, ui::shared, 30, 654, 14, ui::txtCont, 600);
|
||||
drawTextWrap(sdPath.c_str(), frameBuffer, ui::shared, 640, 654, 14, ui::txtCont, 600);
|
||||
|
||||
//OH BOY HERE WE GO
|
||||
if(down & KEY_A)
|
||||
{
|
||||
commit = commitOnWrite;
|
||||
saveMenu.setParams(30, 98, 602);
|
||||
sdMenu.setParams(648, 98, 602);
|
||||
copyMenu.setParams(472, 278, 304);
|
||||
|
||||
savePath = svDev, dev = svDev;
|
||||
sdPath = "sdmc:/";
|
||||
|
||||
saveList.reassign(savePath);
|
||||
sdList.reassign(sdPath);
|
||||
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
|
||||
advMenuCtrl = 0;
|
||||
}
|
||||
|
||||
void updateAdvMode(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
//0 = save; 1 = sd; 2 = cpy
|
||||
switch(advMenuCtrl)
|
||||
{
|
||||
//save
|
||||
case 0:
|
||||
saveMenu.handleInput(down, held);
|
||||
{
|
||||
int saveSel = saveMenu.getSelected();
|
||||
if(saveSel == 1 && savePath != dev)
|
||||
{
|
||||
util::removeLastFolderFromString(savePath);
|
||||
|
||||
saveList.reassign(savePath);
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
else if(saveSel > 1 && saveList.isDir(saveSel - 2))
|
||||
{
|
||||
savePath += saveList.getItem(saveSel - 2) + "/";
|
||||
|
||||
saveList.reassign(savePath);
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//sd
|
||||
case 1:
|
||||
{
|
||||
int sdSel = sdMenu.getSelected();
|
||||
if(sdSel == 1 && sdPath != "sdmc:/")
|
||||
{
|
||||
util::removeLastFolderFromString(sdPath);
|
||||
|
||||
sdList.reassign(sdPath);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
}
|
||||
else if(sdSel > 1 && sdList.isDir(sdSel - 2))
|
||||
{
|
||||
sdPath += sdList.getItem(sdSel - 2) + "/";
|
||||
|
||||
sdList.reassign(sdPath);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//advanced mode
|
||||
case 2:
|
||||
performCopyMenuOps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
//save
|
||||
if(advMenuCtrl == 0 && savePath != dev)
|
||||
{
|
||||
util::removeLastFolderFromString(savePath);
|
||||
|
||||
saveList.reassign(savePath);
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
//sd
|
||||
else if(advMenuCtrl == 1 && sdPath != "sdmc:/")
|
||||
{
|
||||
util::removeLastFolderFromString(sdPath);
|
||||
|
||||
sdList.reassign(sdPath);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
}
|
||||
else if(advMenuCtrl == 2)
|
||||
advMenuCtrl = advPrev;
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(advMenuCtrl == 2)
|
||||
{
|
||||
advMenuCtrl = advPrev;
|
||||
}
|
||||
else
|
||||
{
|
||||
advPrev = advMenuCtrl;
|
||||
advMenuCtrl = 2;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_ZL || down & KEY_ZR)
|
||||
{
|
||||
if(advMenuCtrl == 0 || advMenuCtrl == 1)
|
||||
{
|
||||
if(advMenuCtrl == 0)
|
||||
advMenuCtrl = 1;
|
||||
else
|
||||
advMenuCtrl = 0;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
if(prevState == EX_MNU)
|
||||
mstate = EX_MNU;
|
||||
else if(prevState == TTL_SEL)
|
||||
mstate = TTL_SEL;
|
||||
else if(ui::textMode)
|
||||
mstate = TXT_FLD;
|
||||
else
|
||||
mstate = FLD_SEL;
|
||||
}
|
||||
|
||||
//draw copy menu if it's supposed to be up
|
||||
if(advMenuCtrl == 2)
|
||||
{
|
||||
switch(advPrev)
|
||||
{
|
||||
case 0:
|
||||
copyMenu.setParams(176, 278, 304);
|
||||
copyMenu.editOpt(0, advMenuStr[0] + "sdmc");
|
||||
ui::drawTextbox(frameBuffer, 168, 236, 320, 268);
|
||||
drawText("SAVE", frameBuffer, ui::shared, 176, 250, 18, ui::txtDiag);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
sdMenu.handleInput(down, held);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
copyMenu.handleInput(down, held);
|
||||
copyMenu.setParams(816, 278, 304);
|
||||
copyMenu.editOpt(0, advMenuStr[0] + dev);
|
||||
ui::drawTextbox(frameBuffer, 808, 236, 320, 268);
|
||||
drawText("SDMC", frameBuffer, ui::shared, 816, 250, 18, ui::txtDiag);
|
||||
break;
|
||||
}
|
||||
|
||||
saveMenu.draw(ui::txtCont);
|
||||
sdMenu.draw(ui::txtCont);
|
||||
|
||||
drawTextWrap(savePath.c_str(), frameBuffer, ui::shared, 30, 654, 14, ui::txtCont, 600);
|
||||
drawTextWrap(sdPath.c_str(), frameBuffer, ui::shared, 640, 654, 14, ui::txtCont, 600);
|
||||
|
||||
//OH BOY HERE WE GO
|
||||
if(down & KEY_A)
|
||||
{
|
||||
switch(advMenuCtrl)
|
||||
{
|
||||
//save
|
||||
case 0:
|
||||
{
|
||||
int saveSel = saveMenu.getSelected();
|
||||
if(saveSel == 1 && savePath != dev)
|
||||
{
|
||||
util::removeLastFolderFromString(savePath);
|
||||
|
||||
saveList.reassign(savePath);
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
else if(saveSel > 1 && saveList.isDir(saveSel - 2))
|
||||
{
|
||||
savePath += saveList.getItem(saveSel - 2) + "/";
|
||||
|
||||
saveList.reassign(savePath);
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//sd
|
||||
case 1:
|
||||
{
|
||||
int sdSel = sdMenu.getSelected();
|
||||
if(sdSel == 1 && sdPath != "sdmc:/")
|
||||
{
|
||||
util::removeLastFolderFromString(sdPath);
|
||||
|
||||
sdList.reassign(sdPath);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
}
|
||||
else if(sdSel > 1 && sdList.isDir(sdSel - 2))
|
||||
{
|
||||
sdPath += sdList.getItem(sdSel - 2) + "/";
|
||||
|
||||
sdList.reassign(sdPath);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//advanced mode
|
||||
case 2:
|
||||
performCopyMenuOps();
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
//save
|
||||
if(advMenuCtrl == 0 && savePath != dev)
|
||||
{
|
||||
util::removeLastFolderFromString(savePath);
|
||||
|
||||
saveList.reassign(savePath);
|
||||
util::copyDirListToMenu(saveList, saveMenu);
|
||||
}
|
||||
//sd
|
||||
else if(advMenuCtrl == 1 && sdPath != "sdmc:/")
|
||||
{
|
||||
util::removeLastFolderFromString(sdPath);
|
||||
|
||||
sdList.reassign(sdPath);
|
||||
util::copyDirListToMenu(sdList, sdMenu);
|
||||
}
|
||||
else if(advMenuCtrl == 2)
|
||||
advMenuCtrl = advPrev;
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(advMenuCtrl == 2)
|
||||
{
|
||||
advMenuCtrl = advPrev;
|
||||
}
|
||||
else
|
||||
{
|
||||
advPrev = advMenuCtrl;
|
||||
advMenuCtrl = 2;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_ZL || down & KEY_ZR)
|
||||
{
|
||||
if(advMenuCtrl == 0 || advMenuCtrl == 1)
|
||||
{
|
||||
if(advMenuCtrl == 0)
|
||||
advMenuCtrl = 1;
|
||||
else
|
||||
advMenuCtrl = 0;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
if(prevState == EX_MNU)
|
||||
mstate = EX_MNU;
|
||||
else if(prevState == TTL_SEL)
|
||||
mstate = TTL_SEL;
|
||||
else if(ui::textMode)
|
||||
mstate = TXT_FLD;
|
||||
else
|
||||
mstate = FLD_SEL;
|
||||
}
|
||||
|
||||
//draw copy menu if it's supposed to be up
|
||||
if(advMenuCtrl == 2)
|
||||
{
|
||||
switch(advPrev)
|
||||
{
|
||||
case 0:
|
||||
copyMenu.setParams(176, 278, 304);
|
||||
copyMenu.editOpt(0, "Copy to SD");
|
||||
ui::drawTextbox(frameBuffer, 168, 236, 320, 268);
|
||||
drawText("SAVE", frameBuffer, ui::shared, 176, 250, 18, ui::txtDiag);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
copyMenu.setParams(816, 278, 304);
|
||||
copyMenu.editOpt(0, "Copy to Save");
|
||||
ui::drawTextbox(frameBuffer, 808, 236, 320, 268);
|
||||
drawText("SDMC", frameBuffer, ui::shared, 816, 250, 18, ui::txtDiag);
|
||||
break;
|
||||
}
|
||||
copyMenu.draw(ui::txtDiag);
|
||||
}
|
||||
copyMenu.draw(ui::txtDiag);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,153 +8,159 @@
|
|||
|
||||
ui::menu folderMenu;
|
||||
|
||||
namespace ui
|
||||
void ui::folderMenuPrepare(data::user& usr, data::titledata& dat)
|
||||
{
|
||||
void folderMenuPrepare(data::user& usr, data::titledata& dat)
|
||||
folderMenu.setParams(466, 98, 730);
|
||||
folderMenu.reset();
|
||||
|
||||
dat.createDir();
|
||||
|
||||
fs::dirList list(dat.getPath());
|
||||
folderMenu.addOpt("New");
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
folderMenu.addOpt(list.getItem(i));
|
||||
|
||||
folderMenu.adjust();
|
||||
}
|
||||
|
||||
void ui::createNewBackup(const uint64_t& held)
|
||||
{
|
||||
std::string folder;
|
||||
|
||||
if(held & KEY_R)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
||||
else if(held & KEY_L)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YDM);
|
||||
else if(held & KEY_ZL)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_HOYSTE);
|
||||
else
|
||||
{
|
||||
folderMenu.setParams(466, 98, 730);
|
||||
folderMenu.reset();
|
||||
|
||||
dat.createDir();
|
||||
|
||||
fs::dirList list(dat.getPath());
|
||||
folderMenu.addOpt("New");
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
folderMenu.addOpt(list.getItem(i));
|
||||
|
||||
folderMenu.adjust();
|
||||
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),
|
||||
data::curUser.getUsernameSafe().c_str(),
|
||||
data::curData.getTitle().length() < 24 ? data::curData.getTitleSafe() : util::generateAbbrev(data::curData)
|
||||
};
|
||||
folder = util::getStringInput("", "Enter a folder name", 64, 7, dict);
|
||||
}
|
||||
|
||||
void updateFolderMenu(const uint64_t& down, const uint64_t& held)
|
||||
if(!folder.empty())
|
||||
{
|
||||
folderMenu.handleInput(down, held);
|
||||
std::string path = data::curData.getPath() + "/" + folder;
|
||||
mkdir(path.c_str(), 777);
|
||||
path += "/";
|
||||
fs::copyDirToDir("sv:/", path);
|
||||
|
||||
//Draw folder menu
|
||||
folderMenu.draw(ui::txtCont);
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
|
||||
data::curData.icon.draw(96, 98);
|
||||
drawTextWrap(folderMenuInfo.c_str(), frameBuffer, ui::shared, 60, 370, 16, ui::txtCont, 360);
|
||||
void ui::overwriteBackup(unsigned ind)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(ind);
|
||||
if(confirm(data::holdOver, ui::confOverwrite.c_str(), folderName.c_str()))
|
||||
{
|
||||
std::string toPath = data::curData.getPath() + folderName + "/";
|
||||
//Delete and recreate
|
||||
fs::delDir(toPath);
|
||||
mkdir(toPath.c_str(), 777);
|
||||
|
||||
if(down & KEY_A)
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::copyDirToDir(root, toPath);
|
||||
}
|
||||
}
|
||||
|
||||
void ui::restoreBackup(unsigned ind)
|
||||
{
|
||||
if((data::curData.getType() != FsSaveDataType_System || data::sysSaveWrite) && folderMenu.getSelected() > 0)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(ind);
|
||||
if(confirm(data::holdRest, ui::confRestore.c_str(), folderName.c_str()))
|
||||
{
|
||||
if(folderMenu.getSelected() == 0)
|
||||
if(data::autoBack)
|
||||
{
|
||||
std::string folder;
|
||||
//Add back 3DS shortcut thing
|
||||
if(held & KEY_R)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
||||
else if(held & KEY_L)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YDM);
|
||||
else if(held & KEY_ZL)
|
||||
folder = data::curUser.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),
|
||||
data::curUser.getUsernameSafe().c_str(),
|
||||
data::curData.getTitle().length() < 24 ? data::curData.getTitleSafe() : util::generateAbbrev(data::curData)
|
||||
};
|
||||
folder = util::getStringInput("", "Enter a folder name", 64, 7, dict);
|
||||
}
|
||||
if(!folder.empty())
|
||||
{
|
||||
std::string path = data::curData.getPath() + "/" + folder;
|
||||
mkdir(path.c_str(), 777);
|
||||
path += "/";
|
||||
std::string autoFolder = data::curData.getPath() + "/AUTO - " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC);
|
||||
mkdir(autoFolder.c_str(), 777);
|
||||
autoFolder += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
fs::copyDirToDir(root, path);
|
||||
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
std::string root = "sv:/";
|
||||
fs::copyDirToDir(root, autoFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(confirm(data::holdOver, ui::confOverwrite.c_str(), folderName.c_str()))
|
||||
{
|
||||
std::string toPath = data::curData.getPath() + folderName + "/";
|
||||
//Delete and recreate
|
||||
fs::delDir(toPath);
|
||||
mkdir(toPath.c_str(), 777);
|
||||
std::string fromPath = data::curData.getPath() + folderName + "/";
|
||||
std::string root = "sv:/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::copyDirToDir(root, toPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
if((data::curData.getType() != FsSaveDataType_System || data::sysSaveWrite) && folderMenu.getSelected() > 0)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(confirm(data::holdRest, ui::confRestore.c_str(), folderName.c_str()))
|
||||
{
|
||||
if(data::autoBack)
|
||||
{
|
||||
std::string autoFolder = data::curData.getPath() + "/AUTO - " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC);
|
||||
mkdir(autoFolder.c_str(), 777);
|
||||
autoFolder += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
fs::copyDirToDir(root, autoFolder);
|
||||
}
|
||||
|
||||
std::string fromPath = data::curData.getPath() + folderName + "/";
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::delDir(root);
|
||||
fsdevCommitDevice("sv");
|
||||
|
||||
fs::copyDirToDirCommit(fromPath, root, "sv");
|
||||
|
||||
//Rescan init folder menu if autobak to show changes
|
||||
if(data::autoBack)
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(folderMenu.getSelected() > 0)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(ui::confirmDelete(folderName))
|
||||
{
|
||||
std::string delPath = data::curData.getPath() + folderName + "/";
|
||||
fs::delDir(delPath);
|
||||
}
|
||||
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
advModePrep("sv:/", true);
|
||||
mstate = ADV_MDE;
|
||||
}
|
||||
else if(down & KEY_ZR && data::curData.getType() != FsSaveDataType_System && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str()))
|
||||
{
|
||||
fs::delDir("sv:/");
|
||||
fs::delDir(root);
|
||||
fsdevCommitDevice("sv");
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
mstate = TTL_SEL;
|
||||
|
||||
fs::copyDirToDirCommit(fromPath, root, "sv");
|
||||
|
||||
//Rescan init folder menu if autobak to show changes
|
||||
if(data::autoBack)
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ui::deleteBackup(unsigned ind)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(ui::confirmDelete(folderName))
|
||||
{
|
||||
std::string delPath = data::curData.getPath() + folderName + "/";
|
||||
fs::delDir(delPath);
|
||||
}
|
||||
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
|
||||
void ui::updateFolderMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
folderMenu.handleInput(down, held);
|
||||
|
||||
//Draw folder menu
|
||||
folderMenu.draw(ui::txtCont);
|
||||
|
||||
data::curData.icon.draw(96, 98);
|
||||
drawTextWrap(folderMenuInfo.c_str(), frameBuffer, ui::shared, 60, 370, 16, ui::txtCont, 360);
|
||||
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
if(folderMenu.getSelected() == 0)
|
||||
ui::createNewBackup(held);
|
||||
else
|
||||
ui::overwriteBackup(folderMenu.getSelected() - 1);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
ui::restoreBackup(folderMenu.getSelected() - 1);
|
||||
else if(down & KEY_X && folderMenu.getSelected() > 0)
|
||||
ui::deleteBackup(folderMenu.getSelected() - 1);
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
advModePrep("sv:/", true);
|
||||
mstate = ADV_MDE;
|
||||
}
|
||||
else if(down & KEY_ZR && data::curData.getType() != FsSaveDataType_System && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str()))
|
||||
{
|
||||
fs::delDir("sv:/");
|
||||
fsdevCommitDevice("sv");
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
mstate = TTL_SEL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
283
src/ui/menu.cpp
283
src/ui/menu.cpp
|
|
@ -8,154 +8,153 @@
|
|||
|
||||
static const clr menuColorLight = clrCreateU32(0xFFF05032), menuColorDark = clrCreateU32(0xFFC5FF00);
|
||||
|
||||
namespace ui
|
||||
|
||||
void ui::menu::setParams(const unsigned& _x, const unsigned& _y, const unsigned& _rW)
|
||||
{
|
||||
void menu::setParams(const unsigned& _x, const unsigned& _y, const unsigned& _rW)
|
||||
{
|
||||
x = _x;
|
||||
y = _y;
|
||||
rW = _rW;
|
||||
rY = _y;
|
||||
}
|
||||
x = _x;
|
||||
y = _y;
|
||||
rW = _rW;
|
||||
rY = _y;
|
||||
}
|
||||
|
||||
void menu::addOpt(const std::string& add)
|
||||
void ui::menu::addOpt(const std::string& add)
|
||||
{
|
||||
if(textGetWidth(add.c_str(), ui::shared, 18) < rW - 32 || rW == 0)
|
||||
opt.push_back(add);
|
||||
else
|
||||
{
|
||||
if(textGetWidth(add.c_str(), ui::shared, 18) < rW - 32 || rW == 0)
|
||||
opt.push_back(add);
|
||||
else
|
||||
std::string tmp;
|
||||
for(unsigned i = 0; i < add.length(); )
|
||||
{
|
||||
std::string tmp;
|
||||
for(unsigned i = 0; i < add.length(); )
|
||||
{
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t untCnt = decode_utf8(&tmpChr, (uint8_t *)&add.c_str()[i]);
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t untCnt = decode_utf8(&tmpChr, (uint8_t *)&add.c_str()[i]);
|
||||
|
||||
tmp += add.substr(i, untCnt);
|
||||
i += untCnt;
|
||||
if(textGetWidth(tmp.c_str(), ui::shared, 18) >= rW - 32)
|
||||
{
|
||||
opt.push_back(tmp);
|
||||
break;
|
||||
}
|
||||
tmp += add.substr(i, untCnt);
|
||||
i += untCnt;
|
||||
if(textGetWidth(tmp.c_str(), ui::shared, 18) >= rW - 32)
|
||||
{
|
||||
opt.push_back(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void menu::editOpt(int ind, const std::string& ch)
|
||||
{
|
||||
opt[ind] = ch;
|
||||
}
|
||||
|
||||
menu::~menu()
|
||||
{
|
||||
opt.clear();
|
||||
}
|
||||
|
||||
void menu::handleInput(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
if( (held & KEY_UP) || (held & KEY_DOWN))
|
||||
fc++;
|
||||
else
|
||||
fc = 0;
|
||||
if(fc > 10)
|
||||
fc = 0;
|
||||
|
||||
int size = opt.size() - 1;
|
||||
if((down & KEY_UP) || ((held & KEY_UP) && fc == 10))
|
||||
{
|
||||
selected--;
|
||||
if(selected < 0)
|
||||
selected = size;
|
||||
|
||||
if((start > selected) && (start > 0))
|
||||
start--;
|
||||
if(size < 15)
|
||||
start = 0;
|
||||
if((selected - 14) > start)
|
||||
start = selected - 14;
|
||||
}
|
||||
else if((down & KEY_DOWN) || ((held & KEY_DOWN) && fc == 10))
|
||||
{
|
||||
selected++;
|
||||
if(selected > size)
|
||||
selected = 0;
|
||||
|
||||
if((selected > (start + 14)) && ((start + 14) < size))
|
||||
start++;
|
||||
if(selected == 0)
|
||||
start = 0;
|
||||
}
|
||||
else if(down & KEY_RIGHT)
|
||||
{
|
||||
selected += 7;
|
||||
if(selected > size)
|
||||
selected = size;
|
||||
if((selected - 14) > start)
|
||||
start = selected - 14;
|
||||
}
|
||||
else if(down & KEY_LEFT)
|
||||
{
|
||||
selected -= 7;
|
||||
if(selected < 0)
|
||||
selected = 0;
|
||||
if(selected < start)
|
||||
start = selected;
|
||||
}
|
||||
}
|
||||
|
||||
void menu::draw(const clr& textClr)
|
||||
{
|
||||
if(opt.size() < 1)
|
||||
return;
|
||||
|
||||
if(clrAdd)
|
||||
{
|
||||
clrSh += 6;
|
||||
if(clrSh >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrSh -= 3;
|
||||
if(clrSh <= 0x00)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
int length = 0;
|
||||
if((opt.size() - 1) < 15)
|
||||
length = opt.size();
|
||||
else
|
||||
length = start + 15;
|
||||
|
||||
for(int i = start; i < length; i++)
|
||||
{
|
||||
if(i == selected)
|
||||
{
|
||||
drawBoundBox(x, y + ((i - start) * 36), rW, 36, clrSh);
|
||||
drawText(opt[i].c_str(), frameBuffer, shared, x + 8, (y + 8) + ((i - start) * 36), 18, ui::thmID == ColorSetId_Light ? menuColorLight : menuColorDark);
|
||||
}
|
||||
else
|
||||
drawText(opt[i].c_str(), frameBuffer, shared, x + 8, (y + 8) + ((i - start) * 36), 18, textClr);
|
||||
}
|
||||
}
|
||||
|
||||
void menu::reset()
|
||||
{
|
||||
opt.clear();
|
||||
start = 0;
|
||||
selected = 0;
|
||||
|
||||
fc = 0;
|
||||
}
|
||||
|
||||
void menu::adjust()
|
||||
{
|
||||
if(selected > (int)opt.size() - 1)
|
||||
selected = opt.size() - 1;
|
||||
|
||||
if(opt.size() < 14)
|
||||
start = 0;
|
||||
else if(opt.size() > 14 && start + 14 > (int)opt.size() - 1)
|
||||
start = opt.size() - 15;
|
||||
}
|
||||
}
|
||||
|
||||
void ui::menu::editOpt(int ind, const std::string& ch)
|
||||
{
|
||||
opt[ind] = ch;
|
||||
}
|
||||
|
||||
ui::menu::~menu()
|
||||
{
|
||||
opt.clear();
|
||||
}
|
||||
|
||||
void ui::menu::handleInput(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
if( (held & KEY_UP) || (held & KEY_DOWN))
|
||||
fc++;
|
||||
else
|
||||
fc = 0;
|
||||
if(fc > 10)
|
||||
fc = 0;
|
||||
|
||||
int size = opt.size() - 1;
|
||||
if((down & KEY_UP) || ((held & KEY_UP) && fc == 10))
|
||||
{
|
||||
selected--;
|
||||
if(selected < 0)
|
||||
selected = size;
|
||||
|
||||
if((start > selected) && (start > 0))
|
||||
start--;
|
||||
if(size < 15)
|
||||
start = 0;
|
||||
if((selected - 14) > start)
|
||||
start = selected - 14;
|
||||
}
|
||||
else if((down & KEY_DOWN) || ((held & KEY_DOWN) && fc == 10))
|
||||
{
|
||||
selected++;
|
||||
if(selected > size)
|
||||
selected = 0;
|
||||
|
||||
if((selected > (start + 14)) && ((start + 14) < size))
|
||||
start++;
|
||||
if(selected == 0)
|
||||
start = 0;
|
||||
}
|
||||
else if(down & KEY_RIGHT)
|
||||
{
|
||||
selected += 7;
|
||||
if(selected > size)
|
||||
selected = size;
|
||||
if((selected - 14) > start)
|
||||
start = selected - 14;
|
||||
}
|
||||
else if(down & KEY_LEFT)
|
||||
{
|
||||
selected -= 7;
|
||||
if(selected < 0)
|
||||
selected = 0;
|
||||
if(selected < start)
|
||||
start = selected;
|
||||
}
|
||||
}
|
||||
|
||||
void ui::menu::draw(const clr& textClr)
|
||||
{
|
||||
if(opt.size() < 1)
|
||||
return;
|
||||
|
||||
if(clrAdd)
|
||||
{
|
||||
clrSh += 6;
|
||||
if(clrSh >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrSh -= 3;
|
||||
if(clrSh <= 0x00)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
int length = 0;
|
||||
if((opt.size() - 1) < 15)
|
||||
length = opt.size();
|
||||
else
|
||||
length = start + 15;
|
||||
|
||||
for(int i = start; i < length; i++)
|
||||
{
|
||||
if(i == selected)
|
||||
{
|
||||
drawBoundBox(x, y + ((i - start) * 36), rW, 36, clrSh);
|
||||
drawText(opt[i].c_str(), frameBuffer, shared, x + 8, (y + 8) + ((i - start) * 36), 18, ui::thmID == ColorSetId_Light ? menuColorLight : menuColorDark);
|
||||
}
|
||||
else
|
||||
drawText(opt[i].c_str(), frameBuffer, shared, x + 8, (y + 8) + ((i - start) * 36), 18, textClr);
|
||||
}
|
||||
}
|
||||
|
||||
void ui::menu::reset()
|
||||
{
|
||||
opt.clear();
|
||||
start = 0;
|
||||
selected = 0;
|
||||
|
||||
fc = 0;
|
||||
}
|
||||
|
||||
void ui::menu::adjust()
|
||||
{
|
||||
if(selected > (int)opt.size() - 1)
|
||||
selected = opt.size() - 1;
|
||||
|
||||
if(opt.size() < 14)
|
||||
start = 0;
|
||||
else if(opt.size() > 14 && start + 14 > (int)opt.size() - 1)
|
||||
start = opt.size() - 15;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,243 +26,242 @@ static const std::string loadGlyphArray[] =
|
|||
"\ue024", "\ue025", "\ue026", "\ue027"
|
||||
};
|
||||
|
||||
namespace ui
|
||||
|
||||
void ui::progBar::update(const uint64_t& _prog)
|
||||
{
|
||||
void progBar::update(const uint64_t& _prog)
|
||||
prog = _prog;
|
||||
|
||||
width = (float)(((float)prog / (float)max) * 576);
|
||||
}
|
||||
|
||||
void ui::progBar::draw(const std::string& text, const std::string& head)
|
||||
{
|
||||
size_t headWidth = textGetWidth(head.c_str(), ui::shared, 20);
|
||||
unsigned headX = (1280 / 2) - (headWidth / 2);
|
||||
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawRect(frameBuffer, 320, 206, 640, 2, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFF6D6D6D) : clrCreateU32(0xFFCCCCCC));
|
||||
drawRect(frameBuffer, 352, 530, 576, 12, clrCreateU32(0xFF666666));
|
||||
drawRect(frameBuffer, 352, 530, (unsigned)width, 12, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFFC5FF00) : clrCreateU32(0xFFF05032));
|
||||
texDraw(ui::progCovLeft, frameBuffer, 352, 530);
|
||||
texDraw(ui::progCovRight, frameBuffer, 920, 530);
|
||||
|
||||
drawText(head.c_str(), frameBuffer, ui::shared, headX, 168, 20, ui::txtDiag);
|
||||
drawTextWrap(text.c_str(), frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
}
|
||||
|
||||
void ui::showMessage(const char *head, const char *fmt, ...)
|
||||
{
|
||||
//fake focus
|
||||
drawRectAlpha(frameBuffer, 0, 0, 1280, 720, clrCreateU32(0xAA0D0D0D));
|
||||
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
|
||||
unsigned headX = (640 / 2) - (textGetWidth(head, ui::shared, 20) / 2);
|
||||
unsigned okX = (640 / 2) - (textGetWidth(okt, ui::shared, 20) / 2);
|
||||
|
||||
while(true)
|
||||
{
|
||||
prog = _prog;
|
||||
hidScanInput();
|
||||
|
||||
width = (float)(((float)prog / (float)max) * 576);
|
||||
}
|
||||
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
|
||||
void progBar::draw(const std::string& text, const std::string& head)
|
||||
{
|
||||
size_t headWidth = textGetWidth(head.c_str(), ui::shared, 20);
|
||||
unsigned headX = (1280 / 2) - (headWidth / 2);
|
||||
if(down)
|
||||
break;
|
||||
|
||||
gfxBeginFrame();
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawRect(frameBuffer, 320, 206, 640, 2, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFF6D6D6D) : clrCreateU32(0xFFCCCCCC));
|
||||
drawRect(frameBuffer, 352, 530, 576, 12, clrCreateU32(0xFF666666));
|
||||
drawRect(frameBuffer, 352, 530, (unsigned)width, 12, ui::thmID == ColorSetId_Light ? clrCreateU32(0xFFC5FF00) : clrCreateU32(0xFFF05032));
|
||||
texDraw(ui::progCovLeft, frameBuffer, 352, 530);
|
||||
texDraw(ui::progCovRight, frameBuffer, 920, 530);
|
||||
|
||||
drawText(head.c_str(), frameBuffer, ui::shared, headX, 168, 20, ui::txtDiag);
|
||||
drawTextWrap(text.c_str(), frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
drawText(head, frameBuffer, ui::shared, 320 + headX, 168, 20, ui::txtDiag);
|
||||
drawTextWrap(tmp, frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
drawText(okt, frameBuffer, ui::shared, 320 + okX, 530, 20, ui::txtDiag);
|
||||
gfxEndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
void showMessage(const char *head, const char *fmt, ...)
|
||||
bool ui::confirm(bool hold, const char *fmt, ...)
|
||||
{
|
||||
//fake focus
|
||||
drawRectAlpha(frameBuffer, 0, 0, 1280, 720, clrCreateU32(0xAA0D0D0D));
|
||||
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
|
||||
bool ret = false, heldDown = false;
|
||||
unsigned loadFrame = 0, holdCount = 0;
|
||||
uint8_t holdClrDiff = 0;
|
||||
clr holdClr = ui::txtDiag;
|
||||
|
||||
unsigned headX = (640 / 2) - (textGetWidth("Confirm", ui::shared, 20) / 2);
|
||||
unsigned yesX = 160 - (textGetWidth(ui::yt.c_str(), ui::shared, 20) / 2);
|
||||
unsigned noX = 160 - (textGetWidth(ui::nt.c_str(), ui::shared, 20) / 2);
|
||||
|
||||
std::string yesText = yt;
|
||||
|
||||
while(true)
|
||||
{
|
||||
//fake focus
|
||||
drawRectAlpha(frameBuffer, 0, 0, 1280, 720, clrCreateU32(0xAA0D0D0D));
|
||||
hidScanInput();
|
||||
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
uint64_t held = hidKeysHeld(CONTROLLER_P1_AUTO);
|
||||
|
||||
unsigned headX = (640 / 2) - (textGetWidth(head, ui::shared, 20) / 2);
|
||||
unsigned okX = (640 / 2) - (textGetWidth(okt, ui::shared, 20) / 2);
|
||||
|
||||
while(true)
|
||||
if(hold && held & KEY_A)
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
|
||||
if(down)
|
||||
break;
|
||||
|
||||
gfxBeginFrame();
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawText(head, frameBuffer, ui::shared, 320 + headX, 168, 20, ui::txtDiag);
|
||||
drawTextWrap(tmp, frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
drawText(okt, frameBuffer, ui::shared, 320 + okX, 530, 20, ui::txtDiag);
|
||||
gfxEndFrame();
|
||||
}
|
||||
}
|
||||
|
||||
bool confirm(bool hold, const char *fmt, ...)
|
||||
{
|
||||
//fake focus
|
||||
drawRectAlpha(frameBuffer, 0, 0, 1280, 720, clrCreateU32(0xAA0D0D0D));
|
||||
|
||||
char tmp[1024];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
|
||||
bool ret = false, heldDown = false;
|
||||
unsigned loadFrame = 0, holdCount = 0;
|
||||
uint8_t holdClrDiff = 0;
|
||||
clr holdClr = ui::txtDiag;
|
||||
|
||||
unsigned headX = (640 / 2) - (textGetWidth("Confirm", ui::shared, 20) / 2);
|
||||
unsigned yesX = 160 - (textGetWidth(ui::yt.c_str(), ui::shared, 20) / 2);
|
||||
unsigned noX = 160 - (textGetWidth(ui::nt.c_str(), ui::shared, 20) / 2);
|
||||
|
||||
std::string yesText = yt;
|
||||
|
||||
while(true)
|
||||
{
|
||||
hidScanInput();
|
||||
|
||||
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
uint64_t held = hidKeysHeld(CONTROLLER_P1_AUTO);
|
||||
|
||||
if(hold && held & KEY_A)
|
||||
heldDown = true;
|
||||
holdCount++, holdClrDiff++;
|
||||
if(holdCount % 4 == 0)
|
||||
{
|
||||
heldDown = true;
|
||||
holdCount++, holdClrDiff++;
|
||||
if(holdCount % 4 == 0)
|
||||
{
|
||||
loadFrame++;
|
||||
if(loadFrame > 7)
|
||||
loadFrame = 0;
|
||||
}
|
||||
|
||||
if(holdCount >= 120)
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(holdCount <= 40)
|
||||
yesText = "(Hold) ";
|
||||
else if(holdCount <= 80)
|
||||
yesText = "(Keep Holding) ";
|
||||
else if(holdCount < 120)
|
||||
yesText = "(Almost There!) ";
|
||||
|
||||
yesText += loadGlyphArray[loadFrame];
|
||||
yesX = 160 - (textGetWidth(yesText.c_str(), ui::shared, 20) / 2);
|
||||
loadFrame++;
|
||||
if(loadFrame > 7)
|
||||
loadFrame = 0;
|
||||
}
|
||||
else if(hold && heldDown)
|
||||
{
|
||||
//Reset everything
|
||||
heldDown= false;
|
||||
holdCount = 0, loadFrame = 0, holdClrDiff = 0;
|
||||
yesX = 160 - (textGetWidth(ui::yt.c_str(), ui::shared, 20) / 2);
|
||||
yesText = ui::yt;
|
||||
holdClr = ui::txtDiag;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
|
||||
if(holdCount >= 120)
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(hold && heldDown)
|
||||
{
|
||||
if(ui::thmID == ColorSetId_Light)
|
||||
holdClr = clrCreateRGBA(0xFF, 0xFF - holdClrDiff, 0xFF - holdClrDiff, 0xFF);
|
||||
else
|
||||
holdClr = clrCreateRGBA(0x25 + holdClrDiff, 0x00, 0x00, 0xFF);
|
||||
}
|
||||
if(holdCount <= 40)
|
||||
yesText = "(Hold) ";
|
||||
else if(holdCount <= 80)
|
||||
yesText = "(Keep Holding) ";
|
||||
else if(holdCount < 120)
|
||||
yesText = "(Almost There!) ";
|
||||
|
||||
gfxBeginFrame();
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawText("Confirm", frameBuffer, ui::shared, 320 + headX, 168, 20, ui::txtDiag);
|
||||
drawText(yesText.c_str(), frameBuffer, ui::shared, 320 + yesX, 530, 20, holdClr);
|
||||
drawText(ui::nt.c_str(), frameBuffer, ui::shared, 860 - noX, 530, 20, ui::txtDiag);
|
||||
drawTextWrap(tmp, frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
gfxEndFrame();
|
||||
yesText += loadGlyphArray[loadFrame];
|
||||
yesX = 160 - (textGetWidth(yesText.c_str(), ui::shared, 20) / 2);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool confirmTransfer(const std::string& f, const std::string& t)
|
||||
{
|
||||
return confirm(false, ui::confCopy.c_str(), f.c_str(), t.c_str());
|
||||
}
|
||||
|
||||
bool confirmDelete(const std::string& p)
|
||||
{
|
||||
return confirm(data::holdDel, ui::confDel.c_str(), p.c_str());
|
||||
}
|
||||
|
||||
void drawTextbox(tex *target, int x, int y, int w, int h)
|
||||
{
|
||||
//Top
|
||||
texDraw(ui::cornerTopLeft, target, x, y);
|
||||
drawRect(target, x + 32, y, w - 64, 32, ui::tboxClr);
|
||||
texDraw(ui::cornerTopRight, target, (x + w) - 32, y);
|
||||
|
||||
//middle
|
||||
drawRect(target, x, y + 32, w, h - 64, tboxClr);
|
||||
|
||||
//bottom
|
||||
texDraw(ui::cornerBottomLeft, target, x, (y + h) - 32);
|
||||
drawRect(target, x + 32, (y + h) - 32, w - 64, 32, tboxClr);
|
||||
texDraw(ui::cornerBottomRight, target, (x + w) - 32, (y + h) - 32);
|
||||
|
||||
}
|
||||
|
||||
void drawTextboxInvert(tex *target, int x, int y, int w, int h)
|
||||
{
|
||||
clr temp = ui::tboxClr;
|
||||
clrInvert(&temp);
|
||||
|
||||
//Top
|
||||
texDrawInvert(ui::cornerTopLeft, target, x, y);
|
||||
drawRect(target, x + 32, y, w - 64, 32, temp);
|
||||
texDrawInvert(ui::cornerTopRight, target, (x + w) - 32, y);
|
||||
|
||||
//middle
|
||||
drawRect(target, x, y + 32, w, h - 64, temp);
|
||||
|
||||
//bottom
|
||||
texDrawInvert(ui::cornerBottomLeft, target, x, (y + h) - 32);
|
||||
drawRect(target, x + 32, (y + h) - 32, w - 64, 32, temp);
|
||||
texDrawInvert(ui::cornerBottomRight, target, (x + w) - 32, (y + h) - 32);
|
||||
}
|
||||
|
||||
void showPopup(const std::string& mess, unsigned frames)
|
||||
{
|
||||
frameCount = 0;
|
||||
frameHold = frames;
|
||||
popWidth = textGetWidth(mess.c_str(), ui::shared, 24) + 32;
|
||||
popX = 640 - (popWidth / 2);
|
||||
|
||||
popText = mess;
|
||||
popY = 721;
|
||||
popState = popRise;
|
||||
popDraw = true;
|
||||
}
|
||||
|
||||
void drawPopup(const uint64_t& down)
|
||||
{
|
||||
if(!popDraw)
|
||||
return;
|
||||
|
||||
switch(popState)
|
||||
else if(hold && heldDown)
|
||||
{
|
||||
case popRise:
|
||||
if(popY > 560)
|
||||
popY -= 24;
|
||||
else
|
||||
popState = popShow;
|
||||
break;
|
||||
|
||||
case popShow:
|
||||
if(frameCount++ >= frameHold || down)
|
||||
popState = popFall;
|
||||
break;
|
||||
|
||||
case popFall:
|
||||
if(popY < 721)
|
||||
popY += 24;
|
||||
else
|
||||
popDraw = false;
|
||||
break;
|
||||
//Reset everything
|
||||
heldDown= false;
|
||||
holdCount = 0, loadFrame = 0, holdClrDiff = 0;
|
||||
yesX = 160 - (textGetWidth(ui::yt.c_str(), ui::shared, 20) / 2);
|
||||
yesText = ui::yt;
|
||||
holdClr = ui::txtDiag;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
drawTextbox(frameBuffer, popX, popY, popWidth, 64);
|
||||
drawText(popText.c_str(), frameBuffer, ui::shared, popX + 16, popY + 20, 24, ui::txtDiag);
|
||||
if(hold && heldDown)
|
||||
{
|
||||
if(ui::thmID == ColorSetId_Light)
|
||||
holdClr = clrCreateRGBA(0xFF, 0xFF - holdClrDiff, 0xFF - holdClrDiff, 0xFF);
|
||||
else
|
||||
holdClr = clrCreateRGBA(0x25 + holdClrDiff, 0x00, 0x00, 0xFF);
|
||||
}
|
||||
|
||||
gfxBeginFrame();
|
||||
texDraw(diaBox, frameBuffer, 320, 150);
|
||||
drawText("Confirm", frameBuffer, ui::shared, 320 + headX, 168, 20, ui::txtDiag);
|
||||
drawText(yesText.c_str(), frameBuffer, ui::shared, 320 + yesX, 530, 20, holdClr);
|
||||
drawText(ui::nt.c_str(), frameBuffer, ui::shared, 860 - noX, 530, 20, ui::txtDiag);
|
||||
drawTextWrap(tmp, frameBuffer, ui::shared, 352, 230, 16, ui::txtDiag, 576);
|
||||
gfxEndFrame();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool ui::confirmTransfer(const std::string& f, const std::string& t)
|
||||
{
|
||||
return confirm(false, ui::confCopy.c_str(), f.c_str(), t.c_str());
|
||||
}
|
||||
|
||||
bool ui::confirmDelete(const std::string& p)
|
||||
{
|
||||
return confirm(data::holdDel, ui::confDel.c_str(), p.c_str());
|
||||
}
|
||||
|
||||
void ui::drawTextbox(tex *target, int x, int y, int w, int h)
|
||||
{
|
||||
//Top
|
||||
texDraw(ui::cornerTopLeft, target, x, y);
|
||||
drawRect(target, x + 32, y, w - 64, 32, ui::tboxClr);
|
||||
texDraw(ui::cornerTopRight, target, (x + w) - 32, y);
|
||||
|
||||
//middle
|
||||
drawRect(target, x, y + 32, w, h - 64, tboxClr);
|
||||
|
||||
//bottom
|
||||
texDraw(ui::cornerBottomLeft, target, x, (y + h) - 32);
|
||||
drawRect(target, x + 32, (y + h) - 32, w - 64, 32, tboxClr);
|
||||
texDraw(ui::cornerBottomRight, target, (x + w) - 32, (y + h) - 32);
|
||||
|
||||
}
|
||||
|
||||
void ui::drawTextboxInvert(tex *target, int x, int y, int w, int h)
|
||||
{
|
||||
clr temp = ui::tboxClr;
|
||||
clrInvert(&temp);
|
||||
|
||||
//Top
|
||||
texDrawInvert(ui::cornerTopLeft, target, x, y);
|
||||
drawRect(target, x + 32, y, w - 64, 32, temp);
|
||||
texDrawInvert(ui::cornerTopRight, target, (x + w) - 32, y);
|
||||
|
||||
//middle
|
||||
drawRect(target, x, y + 32, w, h - 64, temp);
|
||||
|
||||
//bottom
|
||||
texDrawInvert(ui::cornerBottomLeft, target, x, (y + h) - 32);
|
||||
drawRect(target, x + 32, (y + h) - 32, w - 64, 32, temp);
|
||||
texDrawInvert(ui::cornerBottomRight, target, (x + w) - 32, (y + h) - 32);
|
||||
}
|
||||
|
||||
void ui::showPopup(const std::string& mess, unsigned frames)
|
||||
{
|
||||
frameCount = 0;
|
||||
frameHold = frames;
|
||||
popWidth = textGetWidth(mess.c_str(), ui::shared, 24) + 32;
|
||||
popX = 640 - (popWidth / 2);
|
||||
|
||||
popText = mess;
|
||||
popY = 721;
|
||||
popState = popRise;
|
||||
popDraw = true;
|
||||
}
|
||||
|
||||
void ui::drawPopup(const uint64_t& down)
|
||||
{
|
||||
if(!popDraw)
|
||||
return;
|
||||
|
||||
switch(popState)
|
||||
{
|
||||
case popRise:
|
||||
if(popY > 560)
|
||||
popY -= 24;
|
||||
else
|
||||
popState = popShow;
|
||||
break;
|
||||
|
||||
case popShow:
|
||||
if(frameCount++ >= frameHold || down)
|
||||
popState = popFall;
|
||||
break;
|
||||
|
||||
case popFall:
|
||||
if(popY < 721)
|
||||
popY += 24;
|
||||
else
|
||||
popDraw = false;
|
||||
break;
|
||||
}
|
||||
|
||||
drawTextbox(frameBuffer, popX, popY, popWidth, 64);
|
||||
drawText(popText.c_str(), frameBuffer, ui::shared, popX + 16, popY + 20, 24, ui::txtDiag);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,181 +7,180 @@
|
|||
#include "util.h"
|
||||
#include "ex.h"
|
||||
|
||||
namespace ui
|
||||
|
||||
void ui::updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
void updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
||||
//Static vars so they don't change on every loop
|
||||
//Where to start in titles, selected title
|
||||
static int start = 0;
|
||||
|
||||
//Color shift for rect
|
||||
static uint8_t clrShft = 0;
|
||||
//Whether or not we're adding or subtracting from clrShft
|
||||
static bool clrAdd = true;
|
||||
|
||||
//Selected rectangle X and Y.
|
||||
static unsigned selRectX = 66, selRectY = 94;
|
||||
|
||||
if(clrAdd)
|
||||
{
|
||||
//Static vars so they don't change on every loop
|
||||
//Where to start in titles, selected title
|
||||
static int start = 0;
|
||||
clrShft += 6;
|
||||
if(clrShft >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrShft -= 3;
|
||||
if(clrShft <= 0)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
//Color shift for rect
|
||||
static uint8_t clrShft = 0;
|
||||
//Whether or not we're adding or subtracting from clrShft
|
||||
static bool clrAdd = true;
|
||||
unsigned x = 70, y = 98;
|
||||
|
||||
//Selected rectangle X and Y.
|
||||
static unsigned selRectX = 66, selRectY = 94;
|
||||
unsigned endTitle = start + 32;
|
||||
if(start + 32 > (int)data::curUser.titles.size())
|
||||
endTitle = data::curUser.titles.size();
|
||||
|
||||
if(clrAdd)
|
||||
//draw Rect so it's always behind icons
|
||||
drawBoundBox(selRectX, selRectY, 140, 140, clrShft);
|
||||
|
||||
for(unsigned i = start; i < endTitle; y += 136)
|
||||
{
|
||||
unsigned endRow = i + 8;
|
||||
for(unsigned tX = x; i < endRow; i++, tX += 144)
|
||||
{
|
||||
clrShft += 6;
|
||||
if(clrShft >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrShft -= 3;
|
||||
if(clrShft <= 0)
|
||||
clrAdd = true;
|
||||
}
|
||||
if(i == endTitle)
|
||||
break;
|
||||
|
||||
unsigned x = 70, y = 98;
|
||||
|
||||
unsigned endTitle = start + 32;
|
||||
if(start + 32 > (int)data::curUser.titles.size())
|
||||
endTitle = data::curUser.titles.size();
|
||||
|
||||
//draw Rect so it's always behind icons
|
||||
drawBoundBox(selRectX, selRectY, 140, 140, clrShft);
|
||||
|
||||
for(unsigned i = start; i < endTitle; y += 136)
|
||||
{
|
||||
unsigned endRow = i + 8;
|
||||
for(unsigned tX = x; i < endRow; i++, tX += 144)
|
||||
if((int)i == data::selData)
|
||||
{
|
||||
if(i == endTitle)
|
||||
break;
|
||||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
|
||||
if((int)i == data::selData)
|
||||
{
|
||||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
std::string title = data::curUser.titles[data::selData].getTitle();
|
||||
unsigned titleWidth = textGetWidth(title.c_str(), ui::shared, 18);
|
||||
int rectWidth = titleWidth + 32, rectX = (tX + 64) - (rectWidth / 2);
|
||||
if(rectX < 16)
|
||||
rectX = 16;
|
||||
else if(rectX + rectWidth > 1264)
|
||||
rectX = 1264 - rectWidth;
|
||||
|
||||
std::string title = data::curUser.titles[data::selData].getTitle();
|
||||
unsigned titleWidth = textGetWidth(title.c_str(), ui::shared, 18);
|
||||
int rectWidth = titleWidth + 32, rectX = (tX + 64) - (rectWidth / 2);
|
||||
if(rectX < 16)
|
||||
rectX = 16;
|
||||
else if(rectX + rectWidth > 1264)
|
||||
rectX = 1264 - rectWidth;
|
||||
|
||||
drawTextbox(frameBuffer, rectX, y - 50, rectWidth, 38);
|
||||
drawText(title.c_str(), frameBuffer, ui::shared, rectX + 16, y - 40, 18, ui::txtDiag);
|
||||
}
|
||||
|
||||
if(data::curUser.titles[i].getFav())
|
||||
data::curUser.titles[i].icon.drawFavHalf(tX, y);
|
||||
else
|
||||
data::curUser.titles[i].icon.drawHalf(tX, y);
|
||||
drawTextbox(frameBuffer, rectX, y - 50, rectWidth, 38);
|
||||
drawText(title.c_str(), frameBuffer, ui::shared, rectX + 16, y - 40, 18, ui::txtDiag);
|
||||
}
|
||||
}
|
||||
|
||||
if(down & KEY_RIGHT)
|
||||
{
|
||||
if(data::selData < (int)data::curUser.titles.size() - 1)
|
||||
data::selData++;
|
||||
|
||||
if(data::selData >= (int)start + 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_LEFT)
|
||||
{
|
||||
if(data::selData > 0)
|
||||
data::selData--;
|
||||
|
||||
if(data::selData < (int)start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
data::selData -= 8;
|
||||
if(data::selData < 0)
|
||||
data::selData = 0;
|
||||
|
||||
if(data::selData < start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_DOWN)
|
||||
{
|
||||
data::selData += 8;
|
||||
if(data::selData > (int)data::curUser.titles.size() - 1)
|
||||
data::selData = data::curUser.titles.size() - 1;
|
||||
|
||||
if(data::selData - start >= 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
data::curData = data::curUser.titles[data::selData];
|
||||
if(fs::mountSave(data::curUser, data::curData))
|
||||
{
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
//Wanna change this sometime
|
||||
ui::folderMenuInfo = util::getInfoString(data::curUser, data::curData);
|
||||
|
||||
mstate = FLD_SEL;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
fs::dumpAllUserSaves(data::curUser);
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(ui::confirm(false, ui::confBlackList.c_str(), data::curUser.titles[data::selData].getTitle().c_str()))
|
||||
data::blacklistAdd(data::curUser, data::curUser.titles[data::selData]);
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64;
|
||||
selRectY = 90;
|
||||
mstate = USR_SEL;
|
||||
return;
|
||||
}
|
||||
else if(down & KEY_L)
|
||||
{
|
||||
if(--data::selUser < 0)
|
||||
data::selUser = data::users.size() - 1;
|
||||
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64, selRectY = 90;
|
||||
data::curUser = data::users[data::selUser];
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_R)
|
||||
{
|
||||
if(++data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = 0;
|
||||
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64, selRectY = 90;
|
||||
data::curUser = data::users[data::selUser];
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
data::titledata tempData = data::curUser.titles[data::selData];
|
||||
if(tempData.getType() == FsSaveDataType_System)
|
||||
ui::showMessage("*NO*", "Deleting system save archives is disabled.");
|
||||
else if(confirm(true, ui::confEraseNand.c_str(), tempData.getTitle().c_str()))
|
||||
{
|
||||
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tempData.getSaveID());
|
||||
data::rescanTitles();
|
||||
data::curUser = data::users[data::selUser];
|
||||
data::selData = 0;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
if(!data::curUser.titles[data::selData].getFav())
|
||||
data::favoriteAdd(data::curUser, data::curUser.titles[data::selData]);
|
||||
if(data::curUser.titles[i].getFav())
|
||||
data::curUser.titles[i].icon.drawFavHalf(tX, y);
|
||||
else
|
||||
data::favoriteRemove(data::curUser, data::curUser.titles[data::selData]);
|
||||
data::curUser.titles[i].icon.drawHalf(tX, y);
|
||||
}
|
||||
}
|
||||
|
||||
if(down & KEY_RIGHT)
|
||||
{
|
||||
if(data::selData < (int)data::curUser.titles.size() - 1)
|
||||
data::selData++;
|
||||
|
||||
if(data::selData >= (int)start + 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_LEFT)
|
||||
{
|
||||
if(data::selData > 0)
|
||||
data::selData--;
|
||||
|
||||
if(data::selData < (int)start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
data::selData -= 8;
|
||||
if(data::selData < 0)
|
||||
data::selData = 0;
|
||||
|
||||
if(data::selData < start)
|
||||
start -= 8;
|
||||
}
|
||||
else if(down & KEY_DOWN)
|
||||
{
|
||||
data::selData += 8;
|
||||
if(data::selData > (int)data::curUser.titles.size() - 1)
|
||||
data::selData = data::curUser.titles.size() - 1;
|
||||
|
||||
if(data::selData - start >= 32)
|
||||
start += 8;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
data::curData = data::curUser.titles[data::selData];
|
||||
if(fs::mountSave(data::curUser, data::curData))
|
||||
{
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
//Wanna change this sometime
|
||||
ui::folderMenuInfo = util::getInfoString(data::curUser, data::curData);
|
||||
|
||||
mstate = FLD_SEL;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
fs::dumpAllUserSaves(data::curUser);
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
if(ui::confirm(false, ui::confBlacklist.c_str(), data::curUser.titles[data::selData].getTitle().c_str()))
|
||||
data::blacklistAdd(data::curUser, data::curUser.titles[data::selData]);
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64;
|
||||
selRectY = 90;
|
||||
mstate = USR_SEL;
|
||||
return;
|
||||
}
|
||||
else if(down & KEY_L)
|
||||
{
|
||||
if(--data::selUser < 0)
|
||||
data::selUser = data::users.size() - 1;
|
||||
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64, selRectY = 90;
|
||||
data::curUser = data::users[data::selUser];
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_R)
|
||||
{
|
||||
if(++data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = 0;
|
||||
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64, selRectY = 90;
|
||||
data::curUser = data::users[data::selUser];
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
data::titledata tempData = data::curUser.titles[data::selData];
|
||||
if(tempData.getType() == FsSaveDataType_System)
|
||||
ui::showMessage("*NO*", "Deleting system save archives is disabled.");
|
||||
else if(confirm(true, ui::confEraseNand.c_str(), tempData.getTitle().c_str()))
|
||||
{
|
||||
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tempData.getSaveID());
|
||||
data::rescanTitles();
|
||||
data::curUser = data::users[data::selUser];
|
||||
data::selData = 0;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(!data::curUser.titles[data::selData].getFav())
|
||||
data::favoriteAdd(data::curUser, data::curUser.titles[data::selData]);
|
||||
else
|
||||
data::favoriteRemove(data::curUser, data::curUser.titles[data::selData]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
889
src/ui/txtui.cpp
889
src/ui/txtui.cpp
|
|
@ -37,534 +37,421 @@ static inline void switchBool(bool& sw)
|
|||
|
||||
static inline std::string getBoolText(bool b)
|
||||
{
|
||||
return b ? "On" : "Off";
|
||||
return b ? ui::on : ui::off;
|
||||
}
|
||||
|
||||
namespace ui
|
||||
void textFolderPrep(data::user& usr, data::titledata& dat)
|
||||
{
|
||||
void textUserPrep()
|
||||
folderMenu.setParams(466, 98, 730);
|
||||
folderMenu.reset();
|
||||
|
||||
dat.createDir();
|
||||
|
||||
fs::dirList list(dat.getPath());
|
||||
folderMenu.addOpt("New");
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
folderMenu.addOpt(list.getItem(i));
|
||||
|
||||
folderMenu.adjust();
|
||||
}
|
||||
|
||||
void ui::textUserPrep()
|
||||
{
|
||||
userMenu.reset();
|
||||
|
||||
userMenu.setParams(76, 98, 310);
|
||||
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
userMenu.addOpt(data::users[i].getUsername());
|
||||
}
|
||||
|
||||
void ui::textTitlePrep(data::user& u)
|
||||
{
|
||||
titleMenu.reset();
|
||||
titleMenu.setParams(76, 98, 310);
|
||||
|
||||
for(unsigned i = 0; i < u.titles.size(); i++)
|
||||
{
|
||||
userMenu.reset();
|
||||
|
||||
userMenu.setParams(76, 98, 310);
|
||||
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
userMenu.addOpt(data::users[i].getUsername());
|
||||
if(u.titles[i].getFav())
|
||||
titleMenu.addOpt("♥ " + u.titles[i].getTitle());
|
||||
else
|
||||
titleMenu.addOpt(u.titles[i].getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
void textTitlePrep(data::user& u)
|
||||
void ui::textUserMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
userMenu.handleInput(down, held);
|
||||
userMenu.draw(ui::txtCont);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
titleMenu.reset();
|
||||
titleMenu.setParams(76, 98, 310);
|
||||
|
||||
for(unsigned i = 0; i < u.titles.size(); i++)
|
||||
if(data::users[userMenu.getSelected()].titles.size() > 0)
|
||||
{
|
||||
if(u.titles[i].getFav())
|
||||
titleMenu.addOpt("♥ " + u.titles[i].getTitle());
|
||||
else
|
||||
titleMenu.addOpt(u.titles[i].getTitle());
|
||||
}
|
||||
}
|
||||
|
||||
void textFolderPrep(data::user& usr, data::titledata& dat)
|
||||
{
|
||||
folderMenu.setParams(466, 98, 730);
|
||||
folderMenu.reset();
|
||||
|
||||
dat.createDir();
|
||||
|
||||
fs::dirList list(dat.getPath());
|
||||
folderMenu.addOpt("New");
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
folderMenu.addOpt(list.getItem(i));
|
||||
|
||||
folderMenu.adjust();
|
||||
}
|
||||
|
||||
void textUserMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
userMenu.handleInput(down, held);
|
||||
userMenu.draw(ui::txtCont);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
if(data::users[userMenu.getSelected()].titles.size() > 0)
|
||||
{
|
||||
data::curUser = data::users[userMenu.getSelected()];
|
||||
textTitlePrep(data::curUser);
|
||||
mstate = TXT_TTL;
|
||||
}
|
||||
else
|
||||
ui::showPopup("No saves available for " + data::users[userMenu.getSelected()].getUsername() + ".", POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
fs::dumpAllUserSaves(data::users[i]);
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
ui::textMode = false;
|
||||
mstate = USR_SEL;
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
fs::unmountSave();
|
||||
ui::exMenuPrep();
|
||||
ui::mstate = EX_MNU;
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
ui::mstate = OPT_MNU;
|
||||
}
|
||||
|
||||
void textTitleMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
titleMenu.handleInput(down, held);
|
||||
titleMenu.draw(ui::txtCont);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
data::curData = data::curUser.titles[titleMenu.getSelected()];
|
||||
|
||||
if(fs::mountSave(data::curUser, data::curData))
|
||||
{
|
||||
textFolderPrep(data::curUser, data::curData);
|
||||
mstate = TXT_FLD;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
fs::dumpAllUserSaves(data::curUser);
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(ui::confirm(false, ui::confBlackList.c_str(), data::curUser.titles[titleMenu.getSelected()].getTitle().c_str()))
|
||||
data::blacklistAdd(data::curUser, data::curUser.titles[titleMenu.getSelected()]);
|
||||
|
||||
data::curUser = data::users[userMenu.getSelected()];
|
||||
textTitlePrep(data::curUser);
|
||||
}
|
||||
else if(down & KEY_L)
|
||||
{
|
||||
if(--data::selUser < 0)
|
||||
data::selUser = data::users.size() - 1;
|
||||
|
||||
data::curUser = data::users[data::selUser];
|
||||
textTitlePrep(data::curUser);
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_R)
|
||||
{
|
||||
if(++data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = 0;
|
||||
|
||||
data::curUser = data::users[data::selUser];
|
||||
textTitlePrep(data::curUser);
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
unsigned sel = titleMenu.getSelected();
|
||||
if(!data::curUser.titles[sel].getFav())
|
||||
data::favoriteAdd(data::curUser, data::curUser.titles[sel]);
|
||||
else
|
||||
data::favoriteRemove(data::curUser, data::curUser.titles[sel]);
|
||||
|
||||
textTitlePrep(data::curUser);
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
data::titledata tempData = data::curUser.titles[titleMenu.getSelected()];
|
||||
if(tempData.getType() == FsSaveDataType_System)
|
||||
ui::showMessage("*NO*", "Deleting system save archives is disabled.");
|
||||
else if(confirm(true, ui::confEraseNand.c_str(), tempData.getTitle().c_str()))
|
||||
{
|
||||
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tempData.getSaveID());
|
||||
|
||||
data::rescanTitles();
|
||||
data::curUser = data::users[data::selUser];
|
||||
ui::textTitlePrep(data::curUser);
|
||||
}
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
mstate = TXT_USR;
|
||||
}
|
||||
|
||||
void textFolderMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
titleMenu.draw(ui::txtCont);
|
||||
folderMenu.handleInput(down, held);
|
||||
folderMenu.draw(ui::txtCont);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
if(folderMenu.getSelected() == 0)
|
||||
{
|
||||
std::string folder;
|
||||
//Add back 3DS shortcut thing
|
||||
if(held & KEY_R)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YMD);
|
||||
else if(held & KEY_L)
|
||||
folder = data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_YDM);
|
||||
else if(held & KEY_ZL)
|
||||
folder = data::curUser.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),
|
||||
data::curUser.getUsernameSafe().c_str(),
|
||||
data::curData.getTitle().length() < 24 ? data::curData.getTitleSafe() : util::generateAbbrev(data::curData)
|
||||
};
|
||||
folder = util::getStringInput("", "New Folder", 64, 7, dict);
|
||||
}
|
||||
if(!folder.empty())
|
||||
{
|
||||
std::string path = data::curData.getPath() + folder;
|
||||
mkdir(path.c_str(), 777);
|
||||
path += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
fs::copyDirToDir(root, path);
|
||||
|
||||
textFolderPrep(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(confirm(data::holdOver, ui::confOverwrite.c_str(), folderName.c_str()))
|
||||
{
|
||||
std::string toPath = data::curData.getPath() + folderName + "/";
|
||||
//Delete and recreate
|
||||
fs::delDir(toPath);
|
||||
mkdir(toPath.c_str(), 777);
|
||||
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::copyDirToDir(root, toPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
if((data::curData.getType() != FsSaveDataType_System || data::sysSaveWrite) && folderMenu.getSelected() > 0)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(confirm(data::holdRest, ui::confRestore.c_str(), folderName.c_str()))
|
||||
{
|
||||
if(data::autoBack)
|
||||
{
|
||||
std::string autoFolder = data::curData.getPath() + "/AUTO - " + data::curUser.getUsernameSafe() + " - " + util::getDateTime(util::DATE_FMT_ASC);
|
||||
mkdir(autoFolder.c_str(), 777);
|
||||
autoFolder += "/";
|
||||
|
||||
std::string root = "sv:/";
|
||||
fs::copyDirToDir(root, autoFolder);
|
||||
}
|
||||
|
||||
std::string fromPath = data::curData.getPath() + folderName + "/";
|
||||
std::string root = "sv:/";
|
||||
|
||||
fs::delDir(root);
|
||||
fsdevCommitDevice("sv");
|
||||
|
||||
fs::copyDirToDirCommit(fromPath, root, "sv");
|
||||
|
||||
if(data::autoBack)
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
if(folderMenu.getSelected() > 0)
|
||||
{
|
||||
fs::dirList list(data::curData.getPath());
|
||||
|
||||
std::string folderName = list.getItem(folderMenu.getSelected() - 1);
|
||||
if(ui::confirmDelete(folderName))
|
||||
{
|
||||
std::string delPath = data::curData.getPath() + folderName + "/";
|
||||
fs::delDir(delPath);
|
||||
}
|
||||
|
||||
textFolderPrep(data::curUser, data::curData);
|
||||
}
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
advModePrep("sv:/", true);
|
||||
mstate = ADV_MDE;
|
||||
}
|
||||
else if(down & KEY_ZR && data::curData.getType() != FsSaveDataType_System && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str()))
|
||||
{
|
||||
fs::delDir("sv:/");
|
||||
fsdevCommitDevice("sv");
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
mstate = TXT_TTL;
|
||||
}
|
||||
else
|
||||
ui::showPopup("No saves available for " + data::users[userMenu.getSelected()].getUsername() + ".", POP_FRAME_DEFAULT);
|
||||
}
|
||||
|
||||
void exMenuPrep()
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
exMenu.reset();
|
||||
exMenu.setParams(76, 98, 310);
|
||||
exMenu.addOpt("SD to SD Browser");
|
||||
exMenu.addOpt("Bis: PRODINFOF");
|
||||
exMenu.addOpt("Bis: SAFE");
|
||||
exMenu.addOpt("Bis: SYSTEM");
|
||||
exMenu.addOpt("Bis: USER");
|
||||
exMenu.addOpt("Remove Downloaded Update");
|
||||
exMenu.addOpt("Terminate Process ID");
|
||||
exMenu.addOpt("Mount System Save ID");
|
||||
exMenu.addOpt("Rescan Titles");
|
||||
exMenu.addOpt("Mount Process RomFS");
|
||||
for(unsigned i = 0; i < data::users.size(); i++)
|
||||
fs::dumpAllUserSaves(data::users[i]);
|
||||
}
|
||||
|
||||
void updateExMenu(const uint64_t& down, const uint64_t& held)
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
exMenu.handleInput(down, held);
|
||||
ui::textMode = false;
|
||||
mstate = USR_SEL;
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
fs::unmountSave();
|
||||
ui::exMenuPrep();
|
||||
ui::mstate = EX_MNU;
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
ui::mstate = OPT_MNU;
|
||||
}
|
||||
|
||||
if(down & KEY_A)
|
||||
void ui::textTitleMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
titleMenu.handleInput(down, held);
|
||||
titleMenu.draw(ui::txtCont);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
data::curData = data::curUser.titles[titleMenu.getSelected()];
|
||||
|
||||
if(fs::mountSave(data::curUser, data::curData))
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
FsFileSystem sv;
|
||||
data::curData.setType(FsSaveDataType_System);
|
||||
switch(exMenu.getSelected())
|
||||
{
|
||||
case 0:
|
||||
data::curData.setType(FsSaveDataType_Bcat);
|
||||
advModePrep("sdmc:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fsdevUnmountDevice("sv");
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_CalibrationFile, "");
|
||||
fsdevMountDevice("prodInfo-f", sv);
|
||||
|
||||
advModePrep("profInfo-f:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_SafeMode, "");
|
||||
fsdevMountDevice("safe", sv);
|
||||
|
||||
advModePrep("safe:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_System, "");
|
||||
fsdevMountDevice("sys", sv);
|
||||
|
||||
advModePrep("sys:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_User, "");
|
||||
fsdevMountDevice("user", sv);
|
||||
|
||||
advModePrep("user:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
{
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_System, "");
|
||||
fsdevMountDevice("sv", sv);
|
||||
std::string delPath = "sv:/Contents/placehld/";
|
||||
|
||||
fs::dirList plcHld(delPath);
|
||||
for(unsigned i = 0; i < plcHld.getCount(); i++)
|
||||
{
|
||||
std::string fullPath = delPath + plcHld.getItem(i);
|
||||
std::remove(fullPath.c_str());
|
||||
}
|
||||
fsdevUnmountDevice("sv");
|
||||
|
||||
if(ui::confirm(false, "Restart?"))
|
||||
{
|
||||
bpcInitialize();
|
||||
bpcRebootSystem();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
std::string idStr = util::getStringInput("0100000000000000", "Enter Process ID", 18, 0, NULL);
|
||||
if(!idStr.empty())
|
||||
{
|
||||
uint64_t termID = std::strtoull(idStr.c_str(), NULL, 16);
|
||||
if(R_SUCCEEDED(pmshellTerminateProgram(termID)))
|
||||
ui::showMessage("Success!", "Process %s successfully shutdown.", idStr.c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
{
|
||||
std::string idStr = util::getStringInput("8000000000000000", "Enter Sys Save ID", 18, 0, NULL);
|
||||
uint64_t mountID = std::strtoull(idStr.c_str(), NULL, 16);
|
||||
if(R_SUCCEEDED(fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, mountID, (AccountUid) {0})))
|
||||
{
|
||||
fsdevMountDevice("sv", sv);
|
||||
advModePrep("sv:/", true);
|
||||
data::curData.setType(FsSaveDataType_SystemBcat);
|
||||
prevState = EX_MNU;
|
||||
mstate = ADV_MDE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data::rescanTitles();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
{
|
||||
FsFileSystem tromfs;
|
||||
Result res = fsOpenDataFileSystemByCurrentProcess(&tromfs);
|
||||
//Result res = romfsMountFromCurrentProcess("tromfs"); << Works too, but is kinda weird
|
||||
if(R_SUCCEEDED(res))
|
||||
{
|
||||
fsdevMountDevice("tromfs", tromfs);
|
||||
advModePrep("tromfs:/", false);
|
||||
data::curData.setType(FsSaveDataType_System);
|
||||
ui::mstate = ADV_MDE;
|
||||
ui::prevState = EX_MNU;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
textFolderPrep(data::curUser, data::curData);
|
||||
mstate = TXT_FLD;
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
if(ui::textMode)
|
||||
mstate = TXT_USR;
|
||||
else
|
||||
mstate = USR_SEL;
|
||||
|
||||
prevState = USR_SEL;
|
||||
}
|
||||
|
||||
exMenu.draw(ui::txtCont);
|
||||
}
|
||||
|
||||
void optMenuInit()
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
optMenu.setParams(76, 98, 310);
|
||||
optMenu.addOpt("Inc. Dev Sv");
|
||||
optMenu.addOpt("Auto Backup");
|
||||
optMenu.addOpt("OverClock");
|
||||
optMenu.addOpt("Hold to Delete");
|
||||
optMenu.addOpt("Hold to Restore");
|
||||
optMenu.addOpt("Hold to Overwrite");
|
||||
optMenu.addOpt("Force Mount");
|
||||
optMenu.addOpt("Account Sys Saves");
|
||||
optMenu.addOpt("Write to Sys Saves");
|
||||
optMenu.addOpt("Text UI Mode");
|
||||
optMenu.addOpt("Direct FS");
|
||||
optMenu.addOpt("Skip User");
|
||||
fs::dumpAllUserSaves(data::curUser);
|
||||
}
|
||||
|
||||
void updateOptMenu(const uint64_t& down, const uint64_t& held)
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
optMenu.handleInput(down, held);
|
||||
if(ui::confirm(false, ui::confBlacklist.c_str(), data::curUser.titles[titleMenu.getSelected()].getTitle().c_str()))
|
||||
data::blacklistAdd(data::curUser, data::curUser.titles[titleMenu.getSelected()]);
|
||||
|
||||
//Update Menu Options to reflect changes
|
||||
optMenu.editOpt(0, "Include Dev Sv: " + getBoolText(data::incDev));
|
||||
optMenu.editOpt(1, "Auto Backup: " + getBoolText(data::autoBack));
|
||||
optMenu.editOpt(2, "Overclock: " + getBoolText(data::ovrClk));
|
||||
optMenu.editOpt(3, "Hold to Delete: " + getBoolText(data::holdDel));
|
||||
optMenu.editOpt(4, "Hold to Restore: " + getBoolText(data::holdRest));
|
||||
optMenu.editOpt(5, "Hold to Overwrite: " + getBoolText(data::holdOver));
|
||||
optMenu.editOpt(6, "Force Mount: " + getBoolText(data::forceMount));
|
||||
optMenu.editOpt(7, "Account Sys. Saves: " + getBoolText(data::accSysSave));
|
||||
optMenu.editOpt(8, "Write To Sys. Saves: " + getBoolText(data::sysSaveWrite));
|
||||
optMenu.editOpt(9, "Text UI Mode: " + getBoolText(ui::textMode));
|
||||
optMenu.editOpt(10, "Direct FS Cmd: " + getBoolText(data::directFsCmd));
|
||||
optMenu.editOpt(11, "Skip User Menu: " + getBoolText(data::skipUser));
|
||||
textTitlePrep(data::curUser);
|
||||
}
|
||||
else if(down & KEY_L)
|
||||
{
|
||||
if(--data::selUser < 0)
|
||||
data::selUser = data::users.size() - 1;
|
||||
|
||||
if(down & KEY_A)
|
||||
data::curUser = data::users[data::selUser];
|
||||
textTitlePrep(data::curUser);
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_R)
|
||||
{
|
||||
if(++data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = 0;
|
||||
|
||||
data::curUser = data::users[data::selUser];
|
||||
textTitlePrep(data::curUser);
|
||||
|
||||
ui::showPopup(data::curUser.getUsername(), POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
unsigned sel = titleMenu.getSelected();
|
||||
if(!data::curUser.titles[sel].getFav())
|
||||
data::favoriteAdd(data::curUser, data::curUser.titles[sel]);
|
||||
else
|
||||
data::favoriteRemove(data::curUser, data::curUser.titles[sel]);
|
||||
|
||||
textTitlePrep(data::curUser);
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
data::titledata tempData = data::curUser.titles[titleMenu.getSelected()];
|
||||
if(tempData.getType() == FsSaveDataType_System)
|
||||
ui::showMessage("*NO*", "Deleting system save archives is disabled.");
|
||||
else if(confirm(true, ui::confEraseNand.c_str(), tempData.getTitle().c_str()))
|
||||
{
|
||||
switch(optMenu.getSelected())
|
||||
{
|
||||
case 0:
|
||||
switchBool(data::incDev);
|
||||
break;
|
||||
fsDeleteSaveDataFileSystemBySaveDataSpaceId(FsSaveDataSpaceId_User, tempData.getSaveID());
|
||||
|
||||
case 1:
|
||||
switchBool(data::autoBack);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switchBool(data::ovrClk);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switchBool(data::holdDel);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
switchBool(data::holdRest);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
switchBool(data::holdOver);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
switchBool(data::forceMount);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
switchBool(data::accSysSave);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
switchBool(data::sysSaveWrite);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
switchBool(ui::textMode);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
switchBool(data::directFsCmd);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
switchBool(data::skipUser);
|
||||
break;
|
||||
}
|
||||
data::rescanTitles();
|
||||
data::curUser = data::users[data::selUser];
|
||||
ui::textTitlePrep(data::curUser);
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
ui::mstate = ui::textMode ? TXT_USR : USR_SEL;
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
mstate = TXT_USR;
|
||||
}
|
||||
|
||||
optMenu.draw(ui::txtCont);
|
||||
drawTextWrap(optHelpStrings[optMenu.getSelected()].c_str(), frameBuffer, ui::shared, 466, 98, 18, ui::txtCont, 730);
|
||||
void ui::textFolderMenuUpdate(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
titleMenu.draw(ui::txtCont);
|
||||
folderMenu.handleInput(down, held);
|
||||
folderMenu.draw(ui::txtCont);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
if(folderMenu.getSelected() == 0)
|
||||
createNewBackup(held);
|
||||
else
|
||||
overwriteBackup(folderMenu.getSelected() - 1);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
restoreBackup(folderMenu.getSelected() - 1);
|
||||
else if(down & KEY_X)
|
||||
deleteBackup(folderMenu.getSelected() - 1);
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
advModePrep("sv:/", true);
|
||||
mstate = ADV_MDE;
|
||||
}
|
||||
else if(down & KEY_ZR && data::curData.getType() != FsSaveDataType_System && confirm(true, ui::confEraseFolder.c_str(), data::curData.getTitle().c_str()))
|
||||
{
|
||||
fs::delDir("sv:/");
|
||||
fsdevCommitDevice("sv");
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
mstate = TXT_TTL;
|
||||
}
|
||||
}
|
||||
|
||||
void ui::exMenuPrep()
|
||||
{
|
||||
exMenu.reset();
|
||||
exMenu.setParams(76, 98, 310);
|
||||
for(unsigned i = 0; i < 10; i++)
|
||||
exMenu.addOpt(ui::exMenuStr[i]);
|
||||
}
|
||||
|
||||
void ui::updateExMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
exMenu.handleInput(down, held);
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
FsFileSystem sv;
|
||||
data::curData.setType(FsSaveDataType_System);
|
||||
switch(exMenu.getSelected())
|
||||
{
|
||||
case 0:
|
||||
data::curData.setType(FsSaveDataType_Bcat);
|
||||
advModePrep("sdmc:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fsdevUnmountDevice("sv");
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_CalibrationFile, "");
|
||||
fsdevMountDevice("prodInfo-f", sv);
|
||||
|
||||
advModePrep("profInfo-f:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_SafeMode, "");
|
||||
fsdevMountDevice("safe", sv);
|
||||
|
||||
advModePrep("safe:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_System, "");
|
||||
fsdevMountDevice("sys", sv);
|
||||
|
||||
advModePrep("sys:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_User, "");
|
||||
fsdevMountDevice("user", sv);
|
||||
|
||||
advModePrep("user:/", false);
|
||||
mstate = ADV_MDE;
|
||||
prevState = EX_MNU;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
{
|
||||
fsOpenBisFileSystem(&sv, FsBisPartitionId_System, "");
|
||||
fsdevMountDevice("sv", sv);
|
||||
std::string delPath = "sv:/Contents/placehld/";
|
||||
|
||||
fs::dirList plcHld(delPath);
|
||||
for(unsigned i = 0; i < plcHld.getCount(); i++)
|
||||
{
|
||||
std::string fullPath = delPath + plcHld.getItem(i);
|
||||
std::remove(fullPath.c_str());
|
||||
}
|
||||
fsdevUnmountDevice("sv");
|
||||
|
||||
if(ui::confirm(false, "Restart?"))
|
||||
{
|
||||
bpcInitialize();
|
||||
bpcRebootSystem();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
{
|
||||
std::string idStr = util::getStringInput("0100000000000000", "Enter Process ID", 18, 0, NULL);
|
||||
if(!idStr.empty())
|
||||
{
|
||||
uint64_t termID = std::strtoull(idStr.c_str(), NULL, 16);
|
||||
if(R_SUCCEEDED(pmshellTerminateProgram(termID)))
|
||||
ui::showMessage("Success!", "Process %s successfully shutdown.", idStr.c_str());
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
{
|
||||
std::string idStr = util::getStringInput("8000000000000000", "Enter Sys Save ID", 18, 0, NULL);
|
||||
uint64_t mountID = std::strtoull(idStr.c_str(), NULL, 16);
|
||||
if(R_SUCCEEDED(fsOpen_SystemSaveData(&sv, FsSaveDataSpaceId_System, mountID, (AccountUid) {0})))
|
||||
{
|
||||
fsdevMountDevice("sv", sv);
|
||||
advModePrep("sv:/", true);
|
||||
data::curData.setType(FsSaveDataType_SystemBcat);
|
||||
prevState = EX_MNU;
|
||||
mstate = ADV_MDE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
data::rescanTitles();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
{
|
||||
FsFileSystem tromfs;
|
||||
Result res = fsOpenDataFileSystemByCurrentProcess(&tromfs);
|
||||
//Result res = romfsMountFromCurrentProcess("tromfs"); << Works too, but is kinda weird
|
||||
if(R_SUCCEEDED(res))
|
||||
{
|
||||
fsdevMountDevice("tromfs", tromfs);
|
||||
advModePrep("tromfs:/", false);
|
||||
data::curData.setType(FsSaveDataType_System);
|
||||
ui::mstate = ADV_MDE;
|
||||
ui::prevState = EX_MNU;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
fsdevUnmountDevice("sv");
|
||||
if(ui::textMode)
|
||||
mstate = TXT_USR;
|
||||
else
|
||||
mstate = USR_SEL;
|
||||
|
||||
prevState = USR_SEL;
|
||||
}
|
||||
|
||||
exMenu.draw(ui::txtCont);
|
||||
}
|
||||
|
||||
void ui::optMenuInit()
|
||||
{
|
||||
optMenu.setParams(76, 98, 310);
|
||||
for(unsigned i = 0; i < 12; i++)
|
||||
optMenu.addOpt(ui::optMenuStr[i]);
|
||||
}
|
||||
|
||||
void ui::updateOptMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
optMenu.handleInput(down, held);
|
||||
|
||||
//Update Menu Options to reflect changes
|
||||
optMenu.editOpt(0, optMenuStr[0] + getBoolText(data::incDev));
|
||||
optMenu.editOpt(1, optMenuStr[1] + getBoolText(data::autoBack));
|
||||
optMenu.editOpt(2, optMenuStr[2] + getBoolText(data::ovrClk));
|
||||
optMenu.editOpt(3, optMenuStr[3] + getBoolText(data::holdDel));
|
||||
optMenu.editOpt(4, optMenuStr[4] + getBoolText(data::holdRest));
|
||||
optMenu.editOpt(5, optMenuStr[5] + getBoolText(data::holdOver));
|
||||
optMenu.editOpt(6, optMenuStr[6] + getBoolText(data::forceMount));
|
||||
optMenu.editOpt(7, optMenuStr[7] + getBoolText(data::accSysSave));
|
||||
optMenu.editOpt(8, optMenuStr[8] + getBoolText(data::sysSaveWrite));
|
||||
optMenu.editOpt(9, optMenuStr[9] + getBoolText(ui::textMode));
|
||||
optMenu.editOpt(10, optMenuStr[10] + getBoolText(data::directFsCmd));
|
||||
optMenu.editOpt(11, optMenuStr[11] + getBoolText(data::skipUser));
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
switch(optMenu.getSelected())
|
||||
{
|
||||
case 0:
|
||||
switchBool(data::incDev);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
switchBool(data::autoBack);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
switchBool(data::ovrClk);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switchBool(data::holdDel);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
switchBool(data::holdRest);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
switchBool(data::holdOver);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
switchBool(data::forceMount);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
switchBool(data::accSysSave);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
switchBool(data::sysSaveWrite);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
switchBool(ui::textMode);
|
||||
break;
|
||||
|
||||
case 10:
|
||||
switchBool(data::directFsCmd);
|
||||
break;
|
||||
|
||||
case 11:
|
||||
switchBool(data::skipUser);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_B)
|
||||
ui::mstate = ui::textMode ? TXT_USR : USR_SEL;
|
||||
|
||||
optMenu.draw(ui::txtCont);
|
||||
drawTextWrap(optHelpStrings[optMenu.getSelected()].c_str(), frameBuffer, ui::shared, 466, 98, 18, ui::txtCont, 730);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,112 +7,111 @@
|
|||
#include "uiupdate.h"
|
||||
#include "file.h"
|
||||
|
||||
namespace ui
|
||||
|
||||
void ui::updateUserMenu(const uint64_t& down, const uint64_t& held)
|
||||
{
|
||||
void updateUserMenu(const uint64_t& down, const uint64_t& held)
|
||||
//Static so they don't get reset every loop
|
||||
static int start = 0;
|
||||
|
||||
static uint8_t clrShft = 0;
|
||||
static bool clrAdd = true;
|
||||
|
||||
static unsigned selRectX = 364, selRectY = 160;
|
||||
|
||||
if(clrAdd)
|
||||
{
|
||||
//Static so they don't get reset every loop
|
||||
static int start = 0;
|
||||
clrShft += 6;
|
||||
if(clrShft >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrShft -= 3;
|
||||
if(clrShft <= 0)
|
||||
clrAdd = true;
|
||||
}
|
||||
|
||||
static uint8_t clrShft = 0;
|
||||
static bool clrAdd = true;
|
||||
unsigned x = 368, y = 164;
|
||||
unsigned endUser = data::users.size();
|
||||
|
||||
static unsigned selRectX = 364, selRectY = 160;
|
||||
drawBoundBox(selRectX, selRectY, 140, 140, clrShft);
|
||||
|
||||
if(clrAdd)
|
||||
for(unsigned i = start; i < endUser; y += 136)
|
||||
{
|
||||
unsigned endRow = i + 4;
|
||||
for(unsigned tX = x; i < endRow; i++, tX += 144)
|
||||
{
|
||||
clrShft += 6;
|
||||
if(clrShft >= 0x72)
|
||||
clrAdd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clrShft -= 3;
|
||||
if(clrShft <= 0)
|
||||
clrAdd = true;
|
||||
}
|
||||
if(i == endUser)
|
||||
break;
|
||||
|
||||
unsigned x = 368, y = 164;
|
||||
unsigned endUser = data::users.size();
|
||||
|
||||
drawBoundBox(selRectX, selRectY, 140, 140, clrShft);
|
||||
|
||||
for(unsigned i = start; i < endUser; y += 136)
|
||||
{
|
||||
unsigned endRow = i + 4;
|
||||
for(unsigned tX = x; i < endRow; i++, tX += 144)
|
||||
if((int)i == data::selUser)
|
||||
{
|
||||
if(i == endUser)
|
||||
break;
|
||||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
|
||||
if((int)i == data::selUser)
|
||||
{
|
||||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
std::string username = data::users[data::selUser].getUsername();
|
||||
unsigned userWidth = textGetWidth(username.c_str(), ui::shared, 18);
|
||||
int userRectWidth = userWidth + 32, userRectX = (tX + 64) - (userRectWidth / 2);
|
||||
if(userRectX < 16)
|
||||
userRectX = 16;
|
||||
else if(userRectX + userRectWidth > 1264)
|
||||
userRectX = 1264 - userRectWidth;
|
||||
|
||||
std::string username = data::users[data::selUser].getUsername();
|
||||
unsigned userWidth = textGetWidth(username.c_str(), ui::shared, 18);
|
||||
int userRectWidth = userWidth + 32, userRectX = (tX + 64) - (userRectWidth / 2);
|
||||
if(userRectX < 16)
|
||||
userRectX = 16;
|
||||
else if(userRectX + userRectWidth > 1264)
|
||||
userRectX = 1264 - userRectWidth;
|
||||
|
||||
drawTextbox(frameBuffer, userRectX, y - 50, userRectWidth, 38);
|
||||
drawText(username.c_str(), frameBuffer, ui::shared, userRectX + 16, y - 40, 18, ui::txtDiag);
|
||||
}
|
||||
data::users[i].drawIconHalf(tX, y);
|
||||
drawTextbox(frameBuffer, userRectX, y - 50, userRectWidth, 38);
|
||||
drawText(username.c_str(), frameBuffer, ui::shared, userRectX + 16, y - 40, 18, ui::txtDiag);
|
||||
}
|
||||
}
|
||||
|
||||
if(down & KEY_RIGHT && data::selUser < (int)data::users.size() - 1)
|
||||
data::selUser++;
|
||||
else if(down & KEY_LEFT && data::selUser > 0)
|
||||
data::selUser--;
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
data::selUser -= 4;
|
||||
if(data::selUser < 0)
|
||||
data::selUser = 0;
|
||||
}
|
||||
else if(down & KEY_DOWN)
|
||||
{
|
||||
data::selUser += 4;
|
||||
if(data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = data::users.size() - 1;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
if(data::users[data::selUser].titles.size() > 0)
|
||||
{
|
||||
data::curUser = data::users[data::selUser];
|
||||
mstate = TTL_SEL;
|
||||
}
|
||||
else
|
||||
ui::showPopup("No Saves available for " + data::users[data::selUser].getUsername() + ".", POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
bool cont = true;
|
||||
for(unsigned i = 0; i < data::users.size() - 2; i++)
|
||||
{
|
||||
if(cont)
|
||||
cont = fs::dumpAllUserSaves(data::users[i]);
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
ui::textMode = true;
|
||||
mstate = TXT_USR;
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
fs::unmountSave();
|
||||
ui::mstate = EX_MNU;
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
ui::mstate = OPT_MNU;
|
||||
data::users[i].drawIconHalf(tX, y);
|
||||
}
|
||||
}
|
||||
|
||||
if(down & KEY_RIGHT && data::selUser < (int)data::users.size() - 1)
|
||||
data::selUser++;
|
||||
else if(down & KEY_LEFT && data::selUser > 0)
|
||||
data::selUser--;
|
||||
else if(down & KEY_UP)
|
||||
{
|
||||
data::selUser -= 4;
|
||||
if(data::selUser < 0)
|
||||
data::selUser = 0;
|
||||
}
|
||||
else if(down & KEY_DOWN)
|
||||
{
|
||||
data::selUser += 4;
|
||||
if(data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = data::users.size() - 1;
|
||||
}
|
||||
else if(down & KEY_A)
|
||||
{
|
||||
if(data::users[data::selUser].titles.size() > 0)
|
||||
{
|
||||
data::curUser = data::users[data::selUser];
|
||||
mstate = TTL_SEL;
|
||||
}
|
||||
else
|
||||
ui::showPopup("No Saves available for " + data::users[data::selUser].getUsername() + ".", POP_FRAME_DEFAULT);
|
||||
}
|
||||
else if(down & KEY_Y)
|
||||
{
|
||||
bool cont = true;
|
||||
for(unsigned i = 0; i < data::users.size() - 2; i++)
|
||||
{
|
||||
if(cont)
|
||||
cont = fs::dumpAllUserSaves(data::users[i]);
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
{
|
||||
ui::textMode = true;
|
||||
mstate = TXT_USR;
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
{
|
||||
fs::unmountSave();
|
||||
ui::mstate = EX_MNU;
|
||||
}
|
||||
else if(down & KEY_MINUS)
|
||||
{
|
||||
ui::mstate = OPT_MNU;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
442
src/util.cpp
442
src/util.cpp
|
|
@ -79,236 +79,232 @@ static inline void replaceCharCStr(char *_s, char _find, char _rep)
|
|||
}
|
||||
}
|
||||
|
||||
namespace util
|
||||
|
||||
std::string util::getDateTime(int fmt)
|
||||
{
|
||||
std::string getDateTime(int fmt)
|
||||
char ret[128];
|
||||
|
||||
time_t raw;
|
||||
time(&raw);
|
||||
tm *Time = localtime(&raw);
|
||||
|
||||
switch(fmt)
|
||||
{
|
||||
char ret[128];
|
||||
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);
|
||||
break;
|
||||
|
||||
time_t raw;
|
||||
time(&raw);
|
||||
tm *Time = localtime(&raw);
|
||||
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);
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
case DATE_FMT_HOYSTE:
|
||||
sprintf(ret, "%02d.%02d.%04d", Time->tm_mday, Time->tm_mon + 1, Time->tm_year + 1900);
|
||||
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);
|
||||
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);
|
||||
break;
|
||||
|
||||
case DATE_FMT_HOYSTE:
|
||||
sprintf(ret, "%02d.%02d.%04d", Time->tm_mday, Time->tm_mon + 1, Time->tm_year + 1900);
|
||||
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);
|
||||
break;
|
||||
|
||||
case DATE_FMT_ASC:
|
||||
strcpy(ret, asctime(Time));
|
||||
replaceCharCStr(ret, ':', '_');
|
||||
replaceCharCStr(ret, '\n', 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
return std::string(ret);
|
||||
case DATE_FMT_ASC:
|
||||
strcpy(ret, asctime(Time));
|
||||
replaceCharCStr(ret, ':', '_');
|
||||
replaceCharCStr(ret, '\n', 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
void copyDirListToMenu(fs::dirList& d, ui::menu& m)
|
||||
{
|
||||
m.reset();
|
||||
m.addOpt(".");
|
||||
m.addOpt("..");
|
||||
for(unsigned i = 0; i < d.getCount(); i++)
|
||||
{
|
||||
if(d.isDir(i))
|
||||
m.addOpt("D " + d.getItem(i));
|
||||
else
|
||||
m.addOpt("F " + d.getItem(i));
|
||||
}
|
||||
|
||||
m.adjust();
|
||||
}
|
||||
|
||||
void removeLastFolderFromString(std::string& _path)
|
||||
{
|
||||
unsigned last = _path.find_last_of('/', _path.length() - 2);
|
||||
_path.erase(last + 1, _path.length());
|
||||
}
|
||||
|
||||
std::string safeString(const std::string& s)
|
||||
{
|
||||
std::string ret = "";
|
||||
for(unsigned i = 0; i < s.length(); )
|
||||
{
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t untCnt = decode_utf8(&tmpChr, (uint8_t *)&s.data()[i]);
|
||||
|
||||
i += untCnt;
|
||||
|
||||
tmpChr = replaceChar(tmpChr);
|
||||
|
||||
if(isVerboten(tmpChr))
|
||||
ret += ' ';
|
||||
else if(tmpChr < 31 || tmpChr > 126)
|
||||
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.erase(ret.length() - 1, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string getInfoString(data::user& u, data::titledata& d)
|
||||
{
|
||||
std::string ret = d.getTitle() + "\n\n";
|
||||
|
||||
ret += "TID: " + d.getTIDStr() + "\n\n";
|
||||
ret += "SID: " + d.getSaveIDStr() + "\n\n";
|
||||
|
||||
switch(d.getType())
|
||||
{
|
||||
case FsSaveDataType_System:
|
||||
ret += "System Save\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Account:
|
||||
ret += "Save Data\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
ret += "BCAT\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
ret += "Device Save\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Temporary:
|
||||
ret += "Temp Storage\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
ret += "Cache Storage\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_SystemBcat:
|
||||
ret += "System BCAT\n\n";
|
||||
break;
|
||||
}
|
||||
|
||||
ret += u.getUsername();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string getStringInput(const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[])
|
||||
{
|
||||
SwkbdConfig swkbd;
|
||||
swkbdCreate(&swkbd, dictCnt);
|
||||
swkbdConfigSetBlurBackground(&swkbd, true);
|
||||
swkbdConfigSetInitialText(&swkbd, def.c_str());
|
||||
swkbdConfigSetHeaderText(&swkbd, head.c_str());
|
||||
swkbdConfigSetGuideText(&swkbd, head.c_str());
|
||||
swkbdConfigSetInitialCursorPos(&swkbd, SwkbdPosEnd);
|
||||
swkbdConfigSetType(&swkbd, SwkbdType_QWERTY);
|
||||
swkbdConfigSetStringLenMax(&swkbd, maxLength);
|
||||
swkbdConfigSetKeySetDisableBitmask(&swkbd, SwkbdKeyDisableBitmask_Backslash | SwkbdKeyDisableBitmask_ForwardSlash | SwkbdKeyDisableBitmask_Percent);
|
||||
swkbdConfigSetDicFlag(&swkbd, 1);
|
||||
|
||||
if(dictCnt > 0)
|
||||
{
|
||||
dictWord words[dictCnt];
|
||||
for(unsigned i = 0; i < dictCnt; i++)
|
||||
swkbdDictWordCreate(&words[i], dictWords[i].c_str(), dictWords[i].c_str());
|
||||
|
||||
swkbdConfigSetDictionary(&swkbd, (SwkbdDictWord *)words, dictCnt);
|
||||
}
|
||||
|
||||
char out[maxLength];
|
||||
memset(out, 0, maxLength);
|
||||
swkbdShow(&swkbd, out, maxLength);
|
||||
swkbdClose(&swkbd);
|
||||
|
||||
return std::string(out);
|
||||
}
|
||||
|
||||
std::string generateAbbrev(data::titledata& dat)
|
||||
{
|
||||
size_t titleLength = dat.getTitle().length();
|
||||
|
||||
char temp[titleLength + 1];
|
||||
memset(temp, 0, titleLength + 1);
|
||||
memcpy(temp, dat.getTitle().c_str(), titleLength);
|
||||
|
||||
std::string ret;
|
||||
char *tok = strtok(temp, " ");
|
||||
while(tok)
|
||||
{
|
||||
ret += tok[0];
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void stripNL(std::string& _s)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = _s.find('\n')) != _s.npos)
|
||||
_s.erase(pos, 1);
|
||||
|
||||
while((pos = _s.find('\r')) != _s.npos)
|
||||
_s.erase(pos, 1);
|
||||
}
|
||||
|
||||
void replaceButtonsInString(std::string& rep)
|
||||
{
|
||||
replaceStr(rep, "[A]", "\ue0e0");
|
||||
replaceStr(rep, "[B]", "\ue0e1");
|
||||
replaceStr(rep, "[X]", "\ue0e2");
|
||||
replaceStr(rep, "[Y]", "\ue0e3");
|
||||
replaceStr(rep, "[L]", "\ue0e4");
|
||||
replaceStr(rep, "[R]", "\ue0e5");
|
||||
replaceStr(rep, "[ZL]", "\ue0e6");
|
||||
replaceStr(rep, "[ZR]", "\ue0e7");
|
||||
replaceStr(rep, "[SL]", "\ue0e8");
|
||||
replaceStr(rep, "[SR]", "\ue0e9");
|
||||
replaceStr(rep, "[DPAD]", "\ue0ea");
|
||||
replaceStr(rep, "[DUP]", "\ue0eb");
|
||||
replaceStr(rep, "[DDOWN]", "\ue0ec");
|
||||
replaceStr(rep, "[DLEFT]", "\ue0ed");
|
||||
replaceStr(rep, "[DRIGHT]", "\ue0ee");
|
||||
replaceStr(rep, "[+]", "\ue0ef");
|
||||
replaceStr(rep, "[-]", "\ue0f0");
|
||||
}
|
||||
|
||||
tex *createIconGeneric(const char *txt)
|
||||
{
|
||||
tex *ret = texCreate(256, 256);
|
||||
texClearColor(ret, ui::rectLt);
|
||||
unsigned int x = 128 - (textGetWidth(txt, ui::shared, 32) / 2);
|
||||
drawText(txt, ret, ui::shared, x, 112, 32, ui::txtCont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void setCPU(uint32_t hz)
|
||||
{
|
||||
if(R_FAILED(clkrstInitialize()))
|
||||
return;
|
||||
|
||||
ClkrstSession cpu;
|
||||
clkrstOpenSession(&cpu, PcvModuleId_CpuBus, 3);
|
||||
clkrstSetClockRate(&cpu, hz);
|
||||
clkrstCloseSession(&cpu);
|
||||
clkrstExit();
|
||||
}
|
||||
return std::string(ret);
|
||||
}
|
||||
|
||||
void util::copyDirListToMenu(fs::dirList& d, ui::menu& m)
|
||||
{
|
||||
m.reset();
|
||||
m.addOpt(".");
|
||||
m.addOpt("..");
|
||||
for(unsigned i = 0; i < d.getCount(); i++)
|
||||
{
|
||||
if(d.isDir(i))
|
||||
m.addOpt("D " + d.getItem(i));
|
||||
else
|
||||
m.addOpt("F " + d.getItem(i));
|
||||
}
|
||||
|
||||
m.adjust();
|
||||
}
|
||||
|
||||
void util::removeLastFolderFromString(std::string& _path)
|
||||
{
|
||||
unsigned last = _path.find_last_of('/', _path.length() - 2);
|
||||
_path.erase(last + 1, _path.length());
|
||||
}
|
||||
|
||||
std::string util::safeString(const std::string& s)
|
||||
{
|
||||
std::string ret = "";
|
||||
for(unsigned i = 0; i < s.length(); )
|
||||
{
|
||||
uint32_t tmpChr = 0;
|
||||
ssize_t untCnt = decode_utf8(&tmpChr, (uint8_t *)&s.data()[i]);
|
||||
|
||||
i += untCnt;
|
||||
|
||||
tmpChr = replaceChar(tmpChr);
|
||||
|
||||
if(isVerboten(tmpChr))
|
||||
ret += ' ';
|
||||
else if(tmpChr < 31 || tmpChr > 126)
|
||||
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.erase(ret.length() - 1, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string util::getInfoString(data::user& u, data::titledata& d)
|
||||
{
|
||||
std::string ret = d.getTitle() + "\n\n";
|
||||
|
||||
ret += "TID: " + d.getTIDStr() + "\n\n";
|
||||
ret += "SID: " + d.getSaveIDStr() + "\n\n";
|
||||
|
||||
switch(d.getType())
|
||||
{
|
||||
case FsSaveDataType_System:
|
||||
ret += "System Save\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Account:
|
||||
ret += "Save Data\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Bcat:
|
||||
ret += "BCAT\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Device:
|
||||
ret += "Device Save\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Temporary:
|
||||
ret += "Temp Storage\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_Cache:
|
||||
ret += "Cache Storage\n\n";
|
||||
break;
|
||||
|
||||
case FsSaveDataType_SystemBcat:
|
||||
ret += "System BCAT\n\n";
|
||||
break;
|
||||
}
|
||||
|
||||
ret += u.getUsername();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string util::getStringInput(const std::string& def, const std::string& head, size_t maxLength, unsigned dictCnt, const std::string dictWords[])
|
||||
{
|
||||
SwkbdConfig swkbd;
|
||||
swkbdCreate(&swkbd, dictCnt);
|
||||
swkbdConfigSetBlurBackground(&swkbd, true);
|
||||
swkbdConfigSetInitialText(&swkbd, def.c_str());
|
||||
swkbdConfigSetHeaderText(&swkbd, head.c_str());
|
||||
swkbdConfigSetGuideText(&swkbd, head.c_str());
|
||||
swkbdConfigSetInitialCursorPos(&swkbd, SwkbdPosEnd);
|
||||
swkbdConfigSetType(&swkbd, SwkbdType_QWERTY);
|
||||
swkbdConfigSetStringLenMax(&swkbd, maxLength);
|
||||
swkbdConfigSetKeySetDisableBitmask(&swkbd, SwkbdKeyDisableBitmask_Backslash | SwkbdKeyDisableBitmask_ForwardSlash | SwkbdKeyDisableBitmask_Percent);
|
||||
swkbdConfigSetDicFlag(&swkbd, 1);
|
||||
|
||||
if(dictCnt > 0)
|
||||
{
|
||||
dictWord words[dictCnt];
|
||||
for(unsigned i = 0; i < dictCnt; i++)
|
||||
swkbdDictWordCreate(&words[i], dictWords[i].c_str(), dictWords[i].c_str());
|
||||
|
||||
swkbdConfigSetDictionary(&swkbd, (SwkbdDictWord *)words, dictCnt);
|
||||
}
|
||||
|
||||
char out[maxLength];
|
||||
memset(out, 0, maxLength);
|
||||
swkbdShow(&swkbd, out, maxLength);
|
||||
swkbdClose(&swkbd);
|
||||
|
||||
return std::string(out);
|
||||
}
|
||||
|
||||
std::string util::generateAbbrev(data::titledata& dat)
|
||||
{
|
||||
size_t titleLength = dat.getTitle().length();
|
||||
|
||||
char temp[titleLength + 1];
|
||||
memset(temp, 0, titleLength + 1);
|
||||
memcpy(temp, dat.getTitle().c_str(), titleLength);
|
||||
|
||||
std::string ret;
|
||||
char *tok = strtok(temp, " ");
|
||||
while(tok)
|
||||
{
|
||||
ret += tok[0];
|
||||
tok = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void util::stripChar(char _c, std::string& _s)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while((pos = _s.find(_c)) != _s.npos)
|
||||
_s.erase(pos, 1);
|
||||
}
|
||||
|
||||
void util::replaceButtonsInString(std::string& rep)
|
||||
{
|
||||
replaceStr(rep, "[A]", "\ue0e0");
|
||||
replaceStr(rep, "[B]", "\ue0e1");
|
||||
replaceStr(rep, "[X]", "\ue0e2");
|
||||
replaceStr(rep, "[Y]", "\ue0e3");
|
||||
replaceStr(rep, "[L]", "\ue0e4");
|
||||
replaceStr(rep, "[R]", "\ue0e5");
|
||||
replaceStr(rep, "[ZL]", "\ue0e6");
|
||||
replaceStr(rep, "[ZR]", "\ue0e7");
|
||||
replaceStr(rep, "[SL]", "\ue0e8");
|
||||
replaceStr(rep, "[SR]", "\ue0e9");
|
||||
replaceStr(rep, "[DPAD]", "\ue0ea");
|
||||
replaceStr(rep, "[DUP]", "\ue0eb");
|
||||
replaceStr(rep, "[DDOWN]", "\ue0ec");
|
||||
replaceStr(rep, "[DLEFT]", "\ue0ed");
|
||||
replaceStr(rep, "[DRIGHT]", "\ue0ee");
|
||||
replaceStr(rep, "[+]", "\ue0ef");
|
||||
replaceStr(rep, "[-]", "\ue0f0");
|
||||
}
|
||||
|
||||
tex *util::createIconGeneric(const char *txt)
|
||||
{
|
||||
tex *ret = texCreate(256, 256);
|
||||
texClearColor(ret, ui::rectLt);
|
||||
unsigned int x = 128 - (textGetWidth(txt, ui::shared, 32) / 2);
|
||||
drawText(txt, ret, ui::shared, x, 112, 32, ui::txtCont);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void util::setCPU(uint32_t hz)
|
||||
{
|
||||
if(R_FAILED(clkrstInitialize()))
|
||||
return;
|
||||
|
||||
ClkrstSession cpu;
|
||||
clkrstOpenSession(&cpu, PcvModuleId_CpuBus, 3);
|
||||
clkrstSetClockRate(&cpu, hz);
|
||||
clkrstCloseSession(&cpu);
|
||||
clkrstExit();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user