mirror of
https://github.com/J-D-K/JKSV.git
synced 2026-03-21 17:24:37 -05:00
Add drawTextf, drawTextfWrap, Add ZIP export (import later)
This commit is contained in:
parent
749c8fd654
commit
633a97a568
4
Makefile
4
Makefile
|
|
@ -38,7 +38,7 @@ INCLUDES := inc
|
|||
EXEFS_SRC := exefs_src
|
||||
APP_TITLE := JKSV
|
||||
APP_AUTHOR := JK
|
||||
APP_VERSION := 06.04.2020
|
||||
APP_VERSION := 06.06.2020
|
||||
ROMFS := romfs
|
||||
ICON := romfs/icon.jpg
|
||||
|
||||
|
|
@ -57,7 +57,7 @@ CXXFLAGS:= $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++17
|
|||
ASFLAGS := -g $(ARCH)
|
||||
LDFLAGS = -specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
|
||||
|
||||
LIBS := `freetype-config --libs` -lpng -ljpeg -lnx
|
||||
LIBS := `freetype-config --libs` -lpng -ljpeg -lz -lminizip -lnx
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
|
|
|||
15
README.MD
15
README.MD
|
|
@ -9,12 +9,12 @@ JKSV on Switch started as a small project/port to test some things and get famil
|
|||
1. Dump and restore save data.
|
||||
* This includes the ability to dump and restore to/from any location on SD by pressing minus and using the Advanced Mode.
|
||||
2. Dump system save data
|
||||
* Dumping this data is allowed, but writing back is not.
|
||||
* Dumping this data is always enabled, but writing back needs to be enabled from the options menu. Writing to this can be very dangerous.
|
||||
3. Open and explore bis storage partitions via the Extras menu
|
||||
* BIS Storage is opened inside a basic filebrowser. The partition's listing is on the left. Your SD is on the right.
|
||||
* Only copying to SD and file properties work on BIS partitions. Writing to and deleting are disabled for now.
|
||||
* Only copying to SD and file properties work on BIS partitions. Writing to and deleting are disabled unless enabled like system save data.
|
||||
4. Misc Extras:
|
||||
* Ability to remove downloaded firmware updates from NAND.
|
||||
* Ability to remove downloaded firmware updates from NAND. This is located in the extras menu (ZR on User selection)
|
||||
* Terminating processes by [ID](https://switchbrew.org/wiki/Title_list#System_Modules). Allowing you to dump normally unopenable system archives.
|
||||
* Mount by System Save [ID](https://switchbrew.org/wiki/Flash_Filesystem#System_Savegames). Normally used when the terminated process makes JKSV unable to rescan titles without the Switch crashing.
|
||||
* Mount and open RomFS of process the homebrew menu takes over (if launched as NRO).
|
||||
|
|
@ -59,6 +59,15 @@ JKSV on Switch started as a small project/port to test some things and get famil
|
|||
* Make Dir creates a folder.
|
||||
* Properties gets file size and directory size.
|
||||
* ZL or ZR Change the controlled menu.
|
||||
|
||||
5. Extras
|
||||
* SD To SD Browser opens the filebrowser with your SD open in both panels
|
||||
* BIS: [X] opens partition [X] in the filebrowser.
|
||||
* Remove Update deletes system updates downloaded from Nintendo and asks to reboot the system to get rid of the update nag.
|
||||
* Terminate Process asks for a title ID to terminate.
|
||||
* Mount System Save asks for the save ID to mount. This is for when JKSV is unable to rescan with a process terminated.
|
||||
* Rescan Titles reloads save data information. This can be used to reload after a process is terminated or when options are changed.
|
||||
* Mount Process RomFS opens the title's romfs that is taken over to launch the homebrew menu. This only works as an NRO. The NSP will only open JKSV's own RomFS.
|
||||
|
||||
**NOTE**: Press Plus to Exit JKSV. JKSV saves all config, favorites, and the blacklist when exited. Pressing the home button and closing that way will not allow this to take place.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ namespace data
|
|||
void saveFav();
|
||||
void loadDefs();
|
||||
|
||||
//Draws some stats to the upper left corner
|
||||
void dispStats();
|
||||
|
||||
//Class to store title info
|
||||
class titledata
|
||||
{
|
||||
|
|
@ -121,7 +124,7 @@ namespace data
|
|||
void restoreDefaultConfig();
|
||||
extern int selUser, selData;
|
||||
extern SetLanguage sysLang;
|
||||
extern bool incDev, autoBack, ovrClk, holdDel, holdRest, holdOver, forceMount, accSysSave, sysSaveWrite, directFsCmd, skipUser;
|
||||
extern bool incDev, autoBack, ovrClk, holdDel, holdRest, holdOver, forceMount, accSysSave, sysSaveWrite, directFsCmd, skipUser, zip;
|
||||
}
|
||||
|
||||
#endif // DATA_H
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <vector>
|
||||
#include <switch.h>
|
||||
#include <dirent.h>
|
||||
#include <minizip/zip.h>
|
||||
|
||||
#include "fsfile.h"
|
||||
#include "data.h"
|
||||
|
|
@ -25,6 +26,9 @@ namespace fs
|
|||
//Recursively copies 'from' to 'to'
|
||||
void copyDirToDir(const std::string& from, const std::string& to);
|
||||
|
||||
//Copies from to zipFile to
|
||||
void copyDirToZip(const std::string& from, zipFile *to);
|
||||
|
||||
//Same as above, but commits data to 'dev' after every file is closed
|
||||
void copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev);
|
||||
|
||||
|
|
|
|||
47
inc/fsfile.h
47
inc/fsfile.h
|
|
@ -38,25 +38,60 @@ FSFILE *fsfopen(const char *_p, uint32_t mode);
|
|||
FSFILE *fsfopenWithSystem(FsFileSystem *_s, const char *_p, uint32_t mode);
|
||||
|
||||
//Closes _f
|
||||
void fsfclose(FSFILE *_f);
|
||||
inline void fsfclose(FSFILE *_f)
|
||||
{
|
||||
if(_f != NULL)
|
||||
{
|
||||
fsFileClose(&_f->_f);
|
||||
free(_f);
|
||||
}
|
||||
}
|
||||
|
||||
//Seeks like stdio
|
||||
void fsfseek(FSFILE *_f, int offset, int origin);
|
||||
inline void fsfseek(FSFILE *_f, int offset, int origin)
|
||||
{
|
||||
switch(origin)
|
||||
{
|
||||
case FS_SEEK_SET:
|
||||
_f->offset = offset;
|
||||
break;
|
||||
|
||||
case FS_SEEK_CUR:
|
||||
_f->offset += offset;
|
||||
break;
|
||||
|
||||
case FS_SEEK_END:
|
||||
_f->offset = offset + _f->fsize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Returns offset
|
||||
size_t fsftell(FSFILE *_f);
|
||||
inline size_t fsftell(FSFILE *_f) { return _f->offset; }
|
||||
|
||||
//Writes buf to file. Automatically resizes _f to fit buf
|
||||
size_t fsfwrite(const void *buf, size_t sz, size_t count, FSFILE *_f);
|
||||
|
||||
//Reads to buff
|
||||
size_t fsfread(void *buf, size_t sz, size_t count, FSFILE *_f);
|
||||
inline size_t fsfread(void *buf, size_t sz, size_t count, FSFILE *_f)
|
||||
{
|
||||
uint64_t read = 0;
|
||||
_f->error = fsFileRead(&_f->_f, _f->offset, buf, sz * count, 0, &read);
|
||||
_f->offset += read;
|
||||
return read;
|
||||
}
|
||||
|
||||
//Gets byte from file
|
||||
char fsfgetc(FSFILE *_f);
|
||||
inline char fsfgetc(FSFILE *_f)
|
||||
{
|
||||
char ret = 0;
|
||||
uint64_t read = 0;
|
||||
_f->error = fsFileRead(&_f->_f, _f->offset++, &ret, 1, 0, &read);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Writes byte to file
|
||||
void fsfputc(int ch, FSFILE *_f);
|
||||
inline void fsfputc(int ch, FSFILE *_f) { fsfwrite(&ch, 1, 1, _f); }
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -81,9 +81,11 @@ inline uint32_t clrGetColor(const clr c)
|
|||
|
||||
//Draws text using f
|
||||
void drawText(const char *str, tex *target, const font *f, int x, int y, int sz, clr c);
|
||||
void drawTextf(tex *target, const font *f, int x, int y, int sz, clr c, const char *fmt, ...);
|
||||
|
||||
//Draws text wrapping lines
|
||||
void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth);
|
||||
void drawTextfWrap(tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth, const char *fmt, ...);
|
||||
|
||||
//Returns text width
|
||||
size_t textGetWidth(const char *str, const font *f, int sz);
|
||||
|
|
|
|||
4
inc/ui.h
4
inc/ui.h
|
|
@ -51,9 +51,9 @@ namespace ui
|
|||
//Strings for extras menu
|
||||
extern std::string exMenuStr[10];
|
||||
//Strings for options menu
|
||||
extern std::string optMenuStr[12];
|
||||
extern std::string optMenuStr[13];
|
||||
//Strings for options explanations
|
||||
extern std::string optMenuExp[12];
|
||||
extern std::string optMenuExp[13];
|
||||
//Strings for the holding thing
|
||||
extern std::string holdingText[3];
|
||||
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ optMenu = 8, "Write to Sys. Saves: "
|
|||
optMenu = 9, "Text UI Mode: "
|
||||
optMenu = 10, "Direct FS Cmd: "
|
||||
optMenu = 11, "Skip User Select: "
|
||||
optMenu = 12, "Export to ZIP: "
|
||||
|
||||
#Explanations of what options do.
|
||||
optMenuExp = 0, "Includes Device Save data in user accounts."
|
||||
|
|
@ -113,3 +114,4 @@ optMenuExp = 8, "Controls whether system save data and partitions can have files
|
|||
optMenuExp = 9, "Changes the UI to be text menu based like the original JKSM for 3DS."
|
||||
optMenuExp = 10, "Directly uses the Switch's FS commands to copy files instead of stdio."
|
||||
optMenuExp = 11, "Skips the user selection screen and jumps directly to the first user account found."
|
||||
optMenuExp = 12, "Exports saves to zip files."
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ extMenu = 1, "BIS: PRODINFOF"
|
|||
extMenu = 2, "BIS: SAFE"
|
||||
extMenu = 3, "BIS: SYSTEM"
|
||||
extMenu = 4, "BIS: USER"
|
||||
extMenu = 5, "撤銷操作與變動"
|
||||
extMenu = 5, "移除系統更新通知"
|
||||
extMenu = 6, "終止指定程序"
|
||||
extMenu = 7, "掛載系統進度"
|
||||
extMenu = 8, "重新掃瞄Titles"
|
||||
|
|
|
|||
27
src/data.cpp
27
src/data.cpp
|
|
@ -21,7 +21,7 @@ SetLanguage data::sysLang;
|
|||
|
||||
//Options
|
||||
bool data::incDev = false, data::autoBack = true, data::ovrClk = false, data::holdDel = true, data::holdRest = true, data::holdOver = true;
|
||||
bool data::forceMount = true, data::accSysSave = false, data::sysSaveWrite = false, data::directFsCmd = false, data::skipUser = false;
|
||||
bool data::forceMount = true, data::accSysSave = false, data::sysSaveWrite = false, data::directFsCmd = false, data::skipUser = false, data::zip = false;
|
||||
|
||||
//For other save types
|
||||
static bool sysBCATPushed = false, cachePushed = false, tempPushed = false;
|
||||
|
|
@ -189,6 +189,10 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
NsApplicationControlData *dat = new NsApplicationControlData;
|
||||
while(R_SUCCEEDED(fsSaveDataInfoReaderRead(&it, &info, 1, &total)) && total != 0)
|
||||
{
|
||||
//Don't bother with this stuff
|
||||
if(blacklisted(info.application_id) || blacklisted(info.save_data_id) || !accountSystemSaveCheck(info) || !testMount(info))
|
||||
continue;
|
||||
|
||||
switch(info.save_data_type)
|
||||
{
|
||||
case FsSaveDataType_Bcat:
|
||||
|
|
@ -227,14 +231,10 @@ bool data::loadUsersTitles(bool clearUsers)
|
|||
break;
|
||||
}
|
||||
|
||||
//Don't bother with this stuff
|
||||
if(blacklisted(info.application_id) || blacklisted(info.save_data_id) || !accountSystemSaveCheck(info) || !testMount(info))
|
||||
continue;
|
||||
|
||||
int u = getUserIndex(info.uid);
|
||||
if(u == -1)
|
||||
{
|
||||
users.emplace(users.end() - 3, info.uid, "");
|
||||
users.emplace(data::users.end() - 3, info.uid, "");
|
||||
u = getUserIndex(info.uid);
|
||||
}
|
||||
users[u].titles.emplace_back(info, dat);
|
||||
|
|
@ -481,6 +481,7 @@ void data::loadCfg()
|
|||
ui::textMode = cfgIn >> 54 & 1;
|
||||
data::directFsCmd = cfgIn >> 53 & 1;
|
||||
data::skipUser = cfgIn >> 52 & 1;
|
||||
data::zip = cfgIn >> 51 & 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -503,6 +504,7 @@ void data::saveCfg()
|
|||
cfgOut |= (uint64_t)ui::textMode << 54;
|
||||
cfgOut |= (uint64_t)data::directFsCmd << 53;
|
||||
cfgOut |= (uint64_t)data::skipUser << 52;
|
||||
cfgOut |= (uint64_t)data::zip << 51;
|
||||
fwrite(&cfgOut, sizeof(uint64_t), 1, cfg);
|
||||
|
||||
fclose(cfg);
|
||||
|
|
@ -557,3 +559,16 @@ void data::loadDefs()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void data::dispStats()
|
||||
{
|
||||
//Easiest/laziest way to do this
|
||||
std::string stats = "User Count: " + std::to_string(users.size()) + "\n";
|
||||
for(data::user& u : data::users)
|
||||
stats += u.getUsername() + ": " + std::to_string(u.titles.size()) + "\n";
|
||||
stats += "Current User: " + data::curUser.getUsername() + "\n";
|
||||
stats += "Current Title: " + data::curData.getTitle() + "\n";
|
||||
stats += "Safe Title: " + data::curData.getTitleSafe() + "\n";
|
||||
stats += "Icon count: " + std::to_string(icons.size()) + "\n";
|
||||
drawText(stats.c_str(), frameBuffer, ui::shared, 2, 2, 16, clrCreateU32(0xFF00DD00));
|
||||
}
|
||||
|
|
|
|||
40
src/file.cpp
40
src/file.cpp
|
|
@ -5,6 +5,7 @@
|
|||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdarg>
|
||||
#include <minizip/zip.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "file.h"
|
||||
|
|
@ -452,6 +453,45 @@ void fs::copyDirToDir(const std::string& from, const std::string& to)
|
|||
}
|
||||
}
|
||||
|
||||
void copyFileToZip(const std::string& from, zipFile *to)
|
||||
{
|
||||
FILE *cpy = fopen(from.c_str(), "rb");
|
||||
|
||||
size_t readIn = 0;
|
||||
uint8_t *inBuff= new uint8_t[BUFF_SIZE];
|
||||
while((readIn = fread(inBuff, 1, BUFF_SIZE, cpy)) > 0)
|
||||
{
|
||||
if(zipWriteInFileInZip(*to, inBuff, readIn) != 0)
|
||||
ui::showMessage("fail", "here");
|
||||
}
|
||||
|
||||
delete[] inBuff;
|
||||
fclose(cpy);
|
||||
}
|
||||
|
||||
void fs::copyDirToZip(const std::string& from, zipFile *to)
|
||||
{
|
||||
fs::dirList list(from);
|
||||
|
||||
for(unsigned i = 0; i < list.getCount(); i++)
|
||||
{
|
||||
if(list.isDir(i))
|
||||
{
|
||||
std::string newFrom = from + list.getItem(i) + "/";
|
||||
fs::copyDirToZip(newFrom, to);
|
||||
}
|
||||
else
|
||||
{
|
||||
zip_fileinfo inf = { 0 };
|
||||
std::string filename = from + list.getItem(i);
|
||||
size_t devPos = filename.find_first_of('/') + 1;
|
||||
if(zipOpenNewFileInZip(*to, filename.substr(devPos, filename.length()).c_str(), &inf, NULL, 0, NULL, 0, "", Z_DEFLATED, Z_DEFAULT_COMPRESSION) == ZIP_OK)
|
||||
copyFileToZip(std::string(from) + list.getItem(i).c_str(), to);
|
||||
zipCloseFileInZip(*to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fs::copyDirToDirCommit(const std::string& from, const std::string& to, const std::string& dev)
|
||||
{
|
||||
dirList list(from);
|
||||
|
|
|
|||
54
src/fsfile.c
54
src/fsfile.c
|
|
@ -107,38 +107,6 @@ FSFILE *fsfopenWithSystem(FsFileSystem *_s, const char *_p, uint32_t mode)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void fsfclose(FSFILE *_f)
|
||||
{
|
||||
if(_f != NULL)
|
||||
{
|
||||
fsFileClose(&_f->_f);
|
||||
free(_f);
|
||||
}
|
||||
}
|
||||
|
||||
void fsfseek(FSFILE *_f, int offset, int origin)
|
||||
{
|
||||
switch(origin)
|
||||
{
|
||||
case FS_SEEK_SET:
|
||||
_f->offset = offset;
|
||||
break;
|
||||
|
||||
case FS_SEEK_CUR:
|
||||
_f->offset += offset;
|
||||
break;
|
||||
|
||||
case FS_SEEK_END:
|
||||
_f->offset = offset + _f->fsize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t fsftell(FSFILE *_f)
|
||||
{
|
||||
return _f->offset;
|
||||
}
|
||||
|
||||
size_t fsfwrite(const void *buf, size_t sz, size_t count, FSFILE *_f)
|
||||
{
|
||||
size_t fullSize = sz * count;
|
||||
|
|
@ -153,25 +121,3 @@ size_t fsfwrite(const void *buf, size_t sz, size_t count, FSFILE *_f)
|
|||
|
||||
return fullSize;
|
||||
}
|
||||
|
||||
size_t fsfread(void *buf, size_t sz, size_t count, FSFILE *_f)
|
||||
{
|
||||
uint64_t read = 0;
|
||||
uint64_t fullSize = sz * count;
|
||||
_f->error = fsFileRead(&_f->_f, _f->offset, buf, fullSize, 0, &read);
|
||||
_f->offset += read;
|
||||
return read;
|
||||
}
|
||||
|
||||
char fsfgetc(FSFILE *_f)
|
||||
{
|
||||
char ret = 0;
|
||||
uint64_t read = 0;
|
||||
_f->error = fsFileRead(&_f->_f, _f->offset++, &ret, 1, 0, &read);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void fsfputc(int ch, FSFILE *_f)
|
||||
{
|
||||
fsfwrite(&ch, 1, 1, _f);
|
||||
}
|
||||
|
|
|
|||
32
src/gfx.c
32
src/gfx.c
|
|
@ -111,6 +111,7 @@ static void drawGlyph(const FT_Bitmap *bmp, tex *target, int _x, int _y)
|
|||
if(bmp->pixel_mode != FT_PIXEL_MODE_GRAY)
|
||||
return;
|
||||
|
||||
clr txClr = textClr, tgtClr;
|
||||
uint8_t *bmpPtr = bmp->buffer;
|
||||
for(int y = _y; y < _y + bmp->rows; y++)
|
||||
{
|
||||
|
|
@ -125,9 +126,8 @@ static void drawGlyph(const FT_Bitmap *bmp, tex *target, int _x, int _y)
|
|||
|
||||
if(*bmpPtr > 0)
|
||||
{
|
||||
clr txClr = clrCreateRGBA(textClr.r, textClr.g, textClr.b, *bmpPtr);
|
||||
clr tgtClr = clrCreateU32(*rowPtr);
|
||||
|
||||
txClr.a = *bmpPtr;
|
||||
tgtClr = clrCreateU32(*rowPtr);
|
||||
*rowPtr = blend(txClr, tgtClr);
|
||||
}
|
||||
}
|
||||
|
|
@ -232,6 +232,17 @@ void drawText(const char *str, tex *target, const font *f, int x, int y, int sz,
|
|||
}
|
||||
}
|
||||
|
||||
void drawTextf(tex *target, const font *f, int x, int y, int sz, clr c, const char *fmt, ...)
|
||||
{
|
||||
char tmp[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
drawText(tmp, target, f, x, y, sz, c);
|
||||
}
|
||||
|
||||
void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth)
|
||||
{
|
||||
char wordBuf[128];
|
||||
|
|
@ -241,10 +252,9 @@ void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int
|
|||
resizeFont(f, sz);
|
||||
textClr = c;
|
||||
|
||||
|
||||
for(unsigned i = 0; i < strLength; )
|
||||
{
|
||||
nextbreak = strcspn(&str[i], " /");
|
||||
nextbreak = strcspn(&str[i], " /_");
|
||||
|
||||
memset(wordBuf, 0, 128);
|
||||
memcpy(wordBuf, &str[i], nextbreak + 1);
|
||||
|
|
@ -316,11 +326,21 @@ void drawTextWrap(const char *str, tex *target, const font *f, int x, int y, int
|
|||
tmpX += slot->advance.x >> 6;
|
||||
}
|
||||
}
|
||||
|
||||
i += strlen(wordBuf);
|
||||
}
|
||||
}
|
||||
|
||||
void drawTextfWrap(tex *target, const font *f, int x, int y, int sz, clr c, int maxWidth, const char *fmt, ...)
|
||||
{
|
||||
char tmp[512];
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsprintf(tmp, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
drawTextWrap(tmp, target, f, x, y, sz, c, maxWidth);
|
||||
}
|
||||
|
||||
size_t textGetWidth(const char *str, const font *f, int sz)
|
||||
{
|
||||
size_t width = 0;
|
||||
|
|
|
|||
10
src/main.cpp
10
src/main.cpp
|
|
@ -37,6 +37,8 @@ extern "C"
|
|||
}
|
||||
}
|
||||
|
||||
bool debDataStats = false;
|
||||
|
||||
int main(int argc, const char *argv[])
|
||||
{
|
||||
fs::init();
|
||||
|
|
@ -52,12 +54,16 @@ int main(int argc, const char *argv[])
|
|||
|
||||
uint64_t down = hidKeysDown(CONTROLLER_P1_AUTO);
|
||||
uint64_t held = hidKeysHeld(CONTROLLER_P1_AUTO);
|
||||
|
||||
if(down & KEY_PLUS)
|
||||
if(held & KEY_LSTICK && held & KEY_RSTICK)
|
||||
debDataStats = true;
|
||||
else if(down & KEY_PLUS)
|
||||
break;
|
||||
|
||||
gfxBeginFrame();
|
||||
ui::runApp(down, held);
|
||||
|
||||
if(debDataStats)
|
||||
data::dispStats();
|
||||
gfxEndFrame();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include "util.h"
|
||||
#include "file.h"
|
||||
|
||||
#define VER_STRING "v. 06.04.2020"
|
||||
#define VER_STRING "v. 06.06.2020"
|
||||
|
||||
//text mode
|
||||
bool ui::textMode = false;
|
||||
|
|
@ -68,8 +68,8 @@ std::string ui::confEraseFolder = "*WARNING*: This *will* delete the current sav
|
|||
std::string ui::noSavesFound = "No saves found for #%s#!";
|
||||
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: " };
|
||||
std::string ui::optMenuExp[12] =
|
||||
std::string ui::optMenuStr[13] = { "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: ", "Export to ZIP: " };
|
||||
std::string ui::optMenuExp[13] =
|
||||
{
|
||||
"Includes Device Save data in user accounts.",
|
||||
"Automatically creates a save backup before restoring a save.",
|
||||
|
|
@ -82,7 +82,8 @@ std::string ui::optMenuExp[12] =
|
|||
"Controls whether system save data and partitions can have files and data written and deleted from them. *This can be extremely dangerous if you don't know what you're doing!*",
|
||||
"Changes the UI to be text menu based like the original JKSM for 3DS.",
|
||||
"Directly uses the Switch's FS commands to copy files instead of stdio.",
|
||||
"Skips the user selection screen and jumps directly to the first user account found."
|
||||
"Skips the user selection screen and jumps directly to the first user account found.",
|
||||
"Exports saves to ZIP files."
|
||||
};
|
||||
std::string ui::holdingText[3] = { "(Hold) ", "(Keep Holding) ", "(Almost there!) " };
|
||||
|
||||
|
|
|
|||
|
|
@ -52,9 +52,22 @@ void ui::createNewBackup(const uint64_t& held)
|
|||
if(!folder.empty())
|
||||
{
|
||||
std::string path = data::curData.getPath() + "/" + folder;
|
||||
mkdir(path.c_str(), 777);
|
||||
path += "/";
|
||||
fs::copyDirToDir("sv:/", path);
|
||||
if(data::zip)
|
||||
{
|
||||
path += ".zip";
|
||||
zipFile cpyTo = zipOpen(path.c_str(), 0);
|
||||
if(cpyTo != NULL)
|
||||
{
|
||||
fs::copyDirToZip("sv:/", &cpyTo);
|
||||
zipClose(cpyTo, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mkdir(path.c_str(), 777);
|
||||
path += "/";
|
||||
fs::copyDirToDir("sv:/", path);
|
||||
}
|
||||
|
||||
folderMenuPrepare(data::curUser, data::curData);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,20 +7,27 @@
|
|||
#include "file.h"
|
||||
#include "util.h"
|
||||
|
||||
//Where to start in titles
|
||||
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;
|
||||
|
||||
static inline void reset()
|
||||
{
|
||||
start = 0;
|
||||
selRectX = 66;
|
||||
selRectY = 94;
|
||||
data::selData = 0;
|
||||
}
|
||||
|
||||
void ui::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)
|
||||
{
|
||||
clrShft += 6;
|
||||
|
|
@ -56,8 +63,7 @@ void ui::updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
|||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
|
||||
std::string title = data::curData.getTitle();
|
||||
unsigned titleWidth = textGetWidth(title.c_str(), ui::shared, 18);
|
||||
unsigned titleWidth = textGetWidth(data::curData.getTitle().c_str(), ui::shared, 18);
|
||||
int rectWidth = titleWidth + 32, rectX = (tX + 64) - (rectWidth / 2);
|
||||
if(rectX < 16)
|
||||
rectX = 16;
|
||||
|
|
@ -65,7 +71,7 @@ void ui::updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
|||
rectX = 1264 - rectWidth;
|
||||
|
||||
drawTextbox(frameBuffer, rectX, y - 50, rectWidth, 38);
|
||||
drawText(title.c_str(), frameBuffer, ui::shared, rectX + 16, y - 40, 18, ui::txtDiag);
|
||||
drawText(data::curData.getTitle().c_str(), frameBuffer, ui::shared, rectX + 16, y - 40, 18, ui::txtDiag);
|
||||
}
|
||||
if(data::curUser.titles[i].getFav())
|
||||
texDrawSkipNoAlpha(data::curUser.titles[i].getIconFav(), frameBuffer, tX, y);
|
||||
|
|
@ -125,10 +131,7 @@ void ui::updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
|||
}
|
||||
else if(down & KEY_B)
|
||||
{
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64;
|
||||
selRectY = 90;
|
||||
reset();
|
||||
mstate = USR_SEL;
|
||||
return;
|
||||
}
|
||||
|
|
@ -137,9 +140,7 @@ void ui::updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
|||
if(--data::selUser < 0)
|
||||
data::selUser = data::users.size() - 1;
|
||||
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64, selRectY = 90;
|
||||
reset();
|
||||
ui::showPopup(POP_FRAME_DEFAULT, data::curUser.getUsername().c_str());
|
||||
}
|
||||
else if(down & KEY_R)
|
||||
|
|
@ -147,9 +148,7 @@ void ui::updateTitleMenu(const uint64_t& down, const uint64_t& held)
|
|||
if(++data::selUser > (int)data::users.size() - 1)
|
||||
data::selUser = 0;
|
||||
|
||||
start = 0;
|
||||
data::selData = 0;
|
||||
selRectX = 64, selRectY = 90;
|
||||
reset();
|
||||
ui::showPopup(POP_FRAME_DEFAULT, data::curUser.getUsername().c_str());
|
||||
}
|
||||
else if(down & KEY_ZR)
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ void ui::updateExMenu(const uint64_t& down, const uint64_t& held)
|
|||
void ui::optMenuInit()
|
||||
{
|
||||
optMenu.setParams(76, 98, 310);
|
||||
for(unsigned i = 0; i < 12; i++)
|
||||
for(unsigned i = 0; i < 13; i++)
|
||||
optMenu.addOpt(ui::optMenuStr[i]);
|
||||
}
|
||||
|
||||
|
|
@ -360,6 +360,7 @@ void ui::updateOptMenu(const uint64_t& down, const uint64_t& held)
|
|||
optMenu.editOpt(9, optMenuStr[9] + getBoolText(ui::textMode));
|
||||
optMenu.editOpt(10, optMenuStr[10] + getBoolText(data::directFsCmd));
|
||||
optMenu.editOpt(11, optMenuStr[11] + getBoolText(data::skipUser));
|
||||
optMenu.editOpt(12, optMenuStr[12] + getBoolText(data::zip));
|
||||
|
||||
if(down & KEY_A)
|
||||
{
|
||||
|
|
@ -412,6 +413,10 @@ void ui::updateOptMenu(const uint64_t& down, const uint64_t& held)
|
|||
case 11:
|
||||
switchBool(data::skipUser);
|
||||
break;
|
||||
|
||||
case 12:
|
||||
switchBool(data::zip);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(down & KEY_X)
|
||||
|
|
|
|||
|
|
@ -48,8 +48,7 @@ void ui::updateUserMenu(const uint64_t& down, const uint64_t& held)
|
|||
selRectX = tX - 6;
|
||||
selRectY = y - 6;
|
||||
|
||||
std::string username = data::users[data::selUser].getUsername();
|
||||
unsigned userWidth = textGetWidth(username.c_str(), ui::shared, 18);
|
||||
unsigned userWidth = textGetWidth(data::curUser.getUsername().c_str(), ui::shared, 18);
|
||||
int userRectWidth = userWidth + 32, userRectX = (tX + 64) - (userRectWidth / 2);
|
||||
if(userRectX < 16)
|
||||
userRectX = 16;
|
||||
|
|
@ -57,7 +56,7 @@ void ui::updateUserMenu(const uint64_t& down, const uint64_t& held)
|
|||
userRectX = 1264 - userRectWidth;
|
||||
|
||||
drawTextbox(frameBuffer, userRectX, y - 50, userRectWidth, 38);
|
||||
drawText(username.c_str(), frameBuffer, ui::shared, userRectX + 16, y - 40, 18, ui::txtDiag);
|
||||
drawText(data::curUser.getUsername().c_str(), frameBuffer, ui::shared, userRectX + 16, y - 40, 18, ui::txtDiag);
|
||||
}
|
||||
data::users[i].drawIconHalf(tX, y);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user