diff --git a/Makefile b/Makefile index e8d8d6d..8e54635 100644 --- a/Makefile +++ b/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 diff --git a/README.MD b/README.MD index 7c8a077..315cc4a 100644 --- a/README.MD +++ b/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. diff --git a/inc/data.h b/inc/data.h index 2ea0a12..0c6884c 100644 --- a/inc/data.h +++ b/inc/data.h @@ -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 diff --git a/inc/file.h b/inc/file.h index 2027d3f..84d552d 100644 --- a/inc/file.h +++ b/inc/file.h @@ -6,6 +6,7 @@ #include #include #include +#include #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); diff --git a/inc/fsfile.h b/inc/fsfile.h index 759dad1..d8076d6 100644 --- a/inc/fsfile.h +++ b/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 diff --git a/inc/gfx.h b/inc/gfx.h index e4c8624..b44d095 100644 --- a/inc/gfx.h +++ b/inc/gfx.h @@ -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); diff --git a/inc/ui.h b/inc/ui.h index 088296c..9241b24 100644 --- a/inc/ui.h +++ b/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]; diff --git a/romfs/lang/en-US.txt b/romfs/lang/en-US.txt index d11ddf7..b4e52d5 100644 --- a/romfs/lang/en-US.txt +++ b/romfs/lang/en-US.txt @@ -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." diff --git a/romfs/lang/zh-TW.txt b/romfs/lang/zh-TW.txt index a50b0bc..7af325f 100644 --- a/romfs/lang/zh-TW.txt +++ b/romfs/lang/zh-TW.txt @@ -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" diff --git a/src/data.cpp b/src/data.cpp index fa835d2..2810427 100644 --- a/src/data.cpp +++ b/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)); +} diff --git a/src/file.cpp b/src/file.cpp index d8b2981..24bf921 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #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); diff --git a/src/fsfile.c b/src/fsfile.c index 94553bb..84b7b7d 100644 --- a/src/fsfile.c +++ b/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); -} diff --git a/src/gfx.c b/src/gfx.c index f2d9cbe..425284c 100644 --- a/src/gfx.c +++ b/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; diff --git a/src/main.cpp b/src/main.cpp index 4d6ad7a..6a7747e 100644 --- a/src/main.cpp +++ b/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(); } diff --git a/src/ui.cpp b/src/ui.cpp index 5f9e918..37b2472 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -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!) " }; diff --git a/src/ui/fldrsel.cpp b/src/ui/fldrsel.cpp index 2d23431..4f67378 100644 --- a/src/ui/fldrsel.cpp +++ b/src/ui/fldrsel.cpp @@ -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); } diff --git a/src/ui/ttlsel.cpp b/src/ui/ttlsel.cpp index f936e72..827e106 100644 --- a/src/ui/ttlsel.cpp +++ b/src/ui/ttlsel.cpp @@ -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) diff --git a/src/ui/txtui.cpp b/src/ui/txtui.cpp index 25d2ce5..462a77f 100644 --- a/src/ui/txtui.cpp +++ b/src/ui/txtui.cpp @@ -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) diff --git a/src/ui/usrsel.cpp b/src/ui/usrsel.cpp index de30623..68caf36 100644 --- a/src/ui/usrsel.cpp +++ b/src/ui/usrsel.cpp @@ -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); }