diff --git a/Makefile b/Makefile index 0d20f19..b60eae8 100644 --- a/Makefile +++ b/Makefile @@ -38,7 +38,7 @@ INCLUDES := inc EXEFS_SRC := exefs_src APP_TITLE := JKSV APP_AUTHOR := JK -APP_VERSION := 03.27.2020 +APP_VERSION := 04.02.2020 ROMFS := romfs #--------------------------------------------------------------------------------- diff --git a/inc/data.h b/inc/data.h index 7d7733a..819a888 100644 --- a/inc/data.h +++ b/inc/data.h @@ -16,6 +16,7 @@ namespace data void loadDataInfo(); void loadBlacklist(); void exit(); + bool isAppletMode(); //Class to help not load the same icons over and over class icn @@ -53,6 +54,7 @@ namespace data //Returns title + title without forbidden chars std::string getTitle() { return title;} std::string getTitleSafe() { return titleSafe; } + std::string getAuthor() { return author; } uint64_t getID() { return id; } FsSaveDataType getType(){ return (FsSaveDataType)info.save_data_type; } @@ -63,7 +65,7 @@ namespace data private: FsSaveDataInfo info; - std::string title, titleSafe; + std::string title, titleSafe, author; uint64_t id; }; @@ -113,8 +115,8 @@ namespace data extern titledata curData; extern user curUser; extern int selUser, selData; - - extern bool isSpcd; + extern std::string sysLang; + extern AppletType appletMode; } #endif // DATA_H diff --git a/inc/util.h b/inc/util.h index aaa1add..bde0a3a 100644 --- a/inc/util.h +++ b/inc/util.h @@ -24,9 +24,6 @@ namespace util //Returns 'JKSV/[title]/' std::string getTitleDir(data::user& u, data::titledata& t); - //Just returns string with '\n' inserted. - std::string getWrappedString(const std::string& s, const unsigned& sz, const unsigned& maxWidth); - //Copys dir list to a menu with 'D: ' + 'F: ' void copyDirListToMenu(fs::dirList& d, ui::menu& m); @@ -41,9 +38,6 @@ namespace util std::string generateAbbrev(data::titledata& dat); - //Loads default icon. - tex *loadDefaultIcon(); - //Creates a basic generic icon for stuff without one tex *createIconGeneric(const char *txt); diff --git a/romfs/img/icn/icnDefault.png b/romfs/img/icn/icnDefault.png index ee52d93..72f6676 100644 Binary files a/romfs/img/icn/icnDefault.png and b/romfs/img/icn/icnDefault.png differ diff --git a/src/data.cpp b/src/data.cpp index 933c642..03bfd44 100644 --- a/src/data.cpp +++ b/src/data.cpp @@ -1,12 +1,10 @@ #include #include #include -#include #include #include #include #include -#include #include "data.h" #include "file.h" @@ -73,23 +71,25 @@ static tex *createDeviceIcon() namespace data { + //Current data titledata curData; user curUser; int selUser = 0, selData = 0; + + //Icon/User vectors std::vector icons; std::vector users; + bool forceMount = true; - bool isSpcd = false; + + //System language + std::string sysLang; + + //AppletType + AppletType appletMode; void loadDataInfo() { - //Check date - time_t raw; - time(&raw); - tm *locTime = localtime(&raw); - if(locTime->tm_mon == 3 && locTime->tm_mday == 1) - isSpcd = true; - //Clear titles + users just in case for(unsigned i = 0; i < users.size(); i++) users[i].titles.clear(); @@ -98,6 +98,14 @@ namespace data loadBlacklist(); + //Get system language and copy to std::string + uint64_t lang; + setGetSystemLanguage(&lang); + data::sysLang.assign((const char *)&lang); + + //Get applet type + appletMode = appletGetAppletType(); + FsSaveDataInfoReader saveIt; s64 total = 0; FsSaveDataInfo info; @@ -188,14 +196,16 @@ namespace data icons[i].deleteData(); } + bool isAppletMode() + { + return appletMode != AppletType_Application && appletMode != AppletType_SystemApplication; + } + void icn::load(const uint64_t& _id, const uint8_t *jpegData, const size_t& jpegSize) { titleID = _id; - if(isSpcd) - iconTex = util::loadDefaultIcon(); - else - iconTex = texLoadJPEGMem(jpegData, jpegSize); + iconTex = texLoadJPEGMem(jpegData, jpegSize); } void icn::load(const uint64_t& _id, const std::string& _png) @@ -248,6 +258,7 @@ namespace data { title.assign(ent->name); titleSafe.assign(util::safeString(title)); + author.assign(ent->author); if(titleSafe.empty()) { char tmp[18]; @@ -308,19 +319,14 @@ namespace data if(username.empty()) username = "Unknown"; userSafe = util::safeString(username); - if(!isSpcd) - { - uint32_t sz = 0; - accountProfileGetImageSize(&prof, &sz); - uint8_t *profJpeg = new uint8_t[sz]; + uint32_t sz = 0; + accountProfileGetImageSize(&prof, &sz); + uint8_t *profJpeg = new uint8_t[sz]; - accountProfileLoadImage(&prof, profJpeg, sz, &sz); - userIcon = texLoadJPEGMem(profJpeg, sz); + accountProfileLoadImage(&prof, profJpeg, sz, &sz); + userIcon = texLoadJPEGMem(profJpeg, sz); - delete[] profJpeg; - } - else - userIcon = util::loadDefaultIcon(); + delete[] profJpeg; accountProfileClose(&prof); @@ -336,7 +342,6 @@ namespace data //create generic icon userIcon = util::createIconGeneric(_backupName.c_str()); - //userIcon = texLoadPNGFile("romfs:/img/icn/icnDefault.png"); return true; } @@ -344,33 +349,34 @@ namespace data void loadBlacklist() { blacklist.clear(); + + char tmp[128]; if(fs::fileExists(fs::getWorkDir() + "blacklist.txt")) { - std::string line; - std::fstream bl(fs::getWorkDir() + "blacklist.txt", std::ios::in); + FILE *bl = fopen(std::string(fs::getWorkDir() + "blacklist.txt").c_str(), "r"); - while(std::getline(bl, line)) + while(fgets(tmp, 128, bl)) { - if(line[0] == '#' || line[0] == '\n') + if(tmp[0] == '#' || tmp[0] == '\n') continue; - blacklist.push_back(std::strtoull(line.c_str(), NULL, 16)); + blacklist.push_back(std::strtoull(tmp, NULL, 16)); } - bl.close(); + fclose(bl); } } void blacklistAdd(user& u, titledata& t) { - std::fstream bl(fs::getWorkDir() + "blacklist.txt", std::ios::app); + FILE *bl = fopen(std::string(fs::getWorkDir() + "blacklist.txt").c_str(), "a"); std::string titleLine = "#" + t.getTitle() + "\n"; char idLine[32]; sprintf(idLine, "0x%016lX\n", t.getID()); - bl.write(titleLine.c_str(), titleLine.length()); - bl.write(idLine, std::strlen(idLine)); - bl.close(); + fputs(titleLine.c_str(), bl); + fputs(idLine, bl); + fclose(bl); //Remove it from every user for(unsigned i = 0; i < users.size(); i++) diff --git a/src/file.cpp b/src/file.cpp index cce266d..9180aad 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -187,29 +186,30 @@ namespace fs void copyFile(const std::string& from, const std::string& to) { - std::fstream f(from, std::ios::in | std::ios::binary); - std::fstream t(to, std::ios::out | std::ios::binary); + FILE *f = fopen(from.c_str(), "rb"); + FILE *t = fopen(to.c_str(), "wb"); - if(!f.is_open() || !t.is_open()) + if(f == NULL || t == NULL) { - f.close(); - t.close(); + //JIC + fclose(f); + fclose(t); return; } - f.seekg(0, f.end); - size_t fileSize = f.tellg(); - f.seekg(0, f.beg); + fseek(f, 0, SEEK_END); + size_t fileSize = ftell(f); + fseek(f, 0, SEEK_SET); uint8_t *buff = new uint8_t[BUFF_SIZE]; ui::progBar prog(fileSize); for(unsigned i = 0; i < fileSize; ) { - f.read((char *)buff, BUFF_SIZE); - t.write((char *)buff, f.gcount()); + size_t readCount = fread(buff, 1, BUFF_SIZE, f); + fwrite(buff, 1, readCount, t); - i += f.gcount(); + i += readCount; prog.update(i); gfxBeginFrame(); @@ -219,35 +219,35 @@ namespace fs delete[] buff; - f.close(); - t.close(); + fclose(f); + fclose(t); } void copyFileCommit(const std::string& from, const std::string& to, const std::string& dev) { - std::fstream f(from, std::ios::in | std::ios::binary); - std::fstream t(to, std::ios::out | std::ios::binary); + FILE *f = fopen(from.c_str(), "rb"); + FILE *t = fopen(to.c_str(), "wb"); - if(!f.is_open() || !t.is_open()) + if(f == NULL || t == NULL) { - f.close(); - t.close(); + fclose(f); + fclose(t); return; } - f.seekg(0, f.end); - size_t fileSize = f.tellg(); - f.seekg(0, f.beg); + fseek(f, 0, SEEK_END); + size_t fileSize = ftell(f); + fseek(f, 0, SEEK_SET); uint8_t *buff = new uint8_t[BUFF_SIZE]; ui::progBar prog(fileSize); for(unsigned i = 0; i < fileSize; ) { - f.read((char *)buff, BUFF_SIZE); - t.write((char *)buff, f.gcount()); + size_t readCount = fread(buff, 1, BUFF_SIZE, f); + fwrite(buff, 1, readCount, t); - i += f.gcount(); + i += readCount; prog.update(i); gfxBeginFrame(); @@ -257,8 +257,8 @@ namespace fs delete[] buff; - f.close(); - t.close(); + fclose(f); + fclose(t); if(R_FAILED(fsdevCommitDevice(dev.c_str()))) ui::showMessage("Error committing file to device!", "*ERROR*"); @@ -362,15 +362,16 @@ namespace fs std::string getFileProps(const std::string& _path) { std::string ret = ""; - std::fstream get(_path, std::ios::in | std::ios::binary); - if(get.is_open()) + + FILE *get = fopen(_path.c_str(), "rb"); + if(get != NULL) { //Size - get.seekg(0, get.end); - unsigned fileSize = get.tellg(); - get.seekg(0, get.beg); + fseek(get, 0, SEEK_END); + unsigned fileSize = ftell(get); + fseek(get, 0, SEEK_SET); - get.close(); + fclose(get); //Probably add more later @@ -405,10 +406,10 @@ namespace fs fileCount++; std::string filePath = _path + list.getItem(i); - std::fstream gSize(filePath.c_str(), std::ios::in | std::ios::binary); - gSize.seekg(0, gSize.end); - size_t fSize = gSize.tellg(); - gSize.close(); + FILE *gSize = fopen(filePath.c_str(), "rb"); + fseek(gSize, 0, SEEK_END); + size_t fSize = ftell(gSize); + fclose(gSize); totalSize += fSize; } diff --git a/src/main.cpp b/src/main.cpp index c300229..cfdff8b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,7 @@ extern "C" hidInitialize(); nsInitialize(); setsysInitialize(); + setInitialize(); accountInitialize(AccountServiceType_System); } @@ -28,6 +29,7 @@ extern "C" hidExit(); nsExit(); setsysExit(); + setExit(); accountExit(); } } diff --git a/src/ui.cpp b/src/ui.cpp index fc406b8..75dd32d 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -11,7 +10,7 @@ #include "util.h" #include "file.h" -#define VER_STRING "v. 03.27.2020" +#define VER_STRING "v. 04.02.2020" //Nav buttons std::vector usrNav, ttlNav, fldNav; diff --git a/src/ui/clsui.cpp b/src/ui/clsui.cpp index bac6141..421f386 100644 --- a/src/ui/clsui.cpp +++ b/src/ui/clsui.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -102,7 +101,6 @@ namespace ui { util::makeTitleDir(data::curUser, data::curData); clsFolderPrep(data::curUser, data::curData); - folderMenuInfo = util::getInfoString(data::curUser, data::curData); mstate = CLS_FLD; } @@ -159,7 +157,7 @@ namespace ui { std::string folder; //Add back 3DS shortcut thing - if(held & KEY_R) + if(held & KEY_R || data::isAppletMode()) 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); @@ -266,8 +264,6 @@ namespace ui devMenu.addOpt("Bis: SAFE"); devMenu.addOpt("Bis: SYSTEM"); devMenu.addOpt("Bis: USER"); - devMenu.addOpt("NAND Backup (exFat)"); - devMenu.addOpt("NAND Backup (FAT32)"); devMenu.addOpt("Remove Downloaded Update"); devMenu.addOpt("Terminate Process ID"); devMenu.addOpt("Mount System Save ID"); @@ -333,107 +329,6 @@ namespace ui break; case 5: - { - fsdevUnmountDevice("sv"); - - FsStorage nand; - fsOpenBisStorage(&nand, FsBisPartitionId_UserDataRoot); - s64 nandSize = 0, offset = 0; - fsStorageGetSize(&nand, &nandSize); - - std::fstream nandOut("sdmc:/JKSV/nand.bin", std::ios::out | std::ios::binary); - - s64 nandBuffSize = 1024 * 1024 * 4; - uint8_t *nandBuff = new uint8_t[nandBuffSize]; - - progBar nandProg(nandSize); - - while(offset < nandSize) - { - size_t readLen = 0; - if(offset + nandBuffSize < nandSize) - readLen = nandBuffSize; - else - readLen = nandSize - offset; - - if(R_SUCCEEDED(fsStorageRead(&nand, offset, nandBuff, readLen))) - { - nandOut.write((char *)nandBuff, readLen); - offset += readLen; - } - else - { - ui::showMessage("Something went wrong while dumping your NAND.", "*ERROR*"); - break; - } - gfxBeginFrame(); - nandProg.update(offset); - nandProg.draw("", "Copying NAND"); - gfxEndFrame(); - } - - delete[] nandBuff; - nandOut.close(); - fsStorageClose(&nand); - } - break; - - case 6: - { - unsigned fcount = 1; - fsdevUnmountDevice("sv"); - - FsStorage nand; - fsOpenBisStorage(&nand, FsBisPartitionId_UserDataRoot); - s64 nandSize = 0, offset = 0; - fsStorageGetSize(&nand, &nandSize); - - std::fstream nandOut("sdmc:/JKSV/nand.bin.00", std::ios::out | std::ios::binary); - - s64 nandBuffSize = 1024 * 1024 * 3; - uint8_t *nandBuff = new uint8_t[nandBuffSize]; - - progBar nandProg(nandSize); - - while(offset < nandSize) - { - size_t readLen = 0; - if(offset + nandBuffSize < nandSize) - readLen = nandBuffSize; - else - readLen = nandSize - offset; - - if(R_SUCCEEDED(fsStorageRead(&nand, offset, nandBuff, readLen))) - { - if((size_t)nandOut.tellp() + readLen >= 0x100000000) - { - nandOut.close(); - char newPath[128]; - sprintf(newPath, "sdmc:/JKSV/nand.bin.%02d", fcount++); - nandOut.open(newPath, std::ios::out | std::ios::binary); - } - nandOut.write((char *)nandBuff, readLen); - offset += readLen; - } - else - { - ui::showMessage("Something went wrong while dumping your NAND.", "*ERROR*"); - break; - } - - gfxBeginFrame(); - nandProg.update(offset); - nandProg.draw("", "Copying NAND"); - gfxEndFrame(); - } - - delete[] nandBuff; - nandOut.close(); - fsStorageClose(&nand); - } - break; - - case 7: { fsdevUnmountDevice("sv"); fsOpenBisFileSystem(&sv, FsBisPartitionId_System, ""); @@ -456,7 +351,7 @@ namespace ui } break; - case 8: + case 6: { fsdevUnmountDevice("sv"); std::string idStr = util::getStringInput("0100000000000000", "Enter Process ID", 18, 0, NULL); @@ -471,7 +366,7 @@ namespace ui } break; - case 9: + case 7: { fsdevUnmountDevice("sv"); std::string idStr = util::getStringInput("8000000000000000", "Enter Sys Save ID", 18, 0, NULL); @@ -487,7 +382,7 @@ namespace ui } break; - case 10: + case 8: { fsdevUnmountDevice("sv"); FsFileSystem tromfs; diff --git a/src/ui/fldrsel.cpp b/src/ui/fldrsel.cpp index cebf5a8..f26d846 100644 --- a/src/ui/fldrsel.cpp +++ b/src/ui/fldrsel.cpp @@ -42,13 +42,14 @@ namespace ui data::curData.icon.draw(96, 98); drawTextWrap(folderMenuInfo.c_str(), frameBuffer, ui::shared, 64, 370, 18, ui::mnuTxt, 224); + if(down & KEY_A || fldNav[0].getEvent() == BUTTON_RELEASED || folderMenu.getTouchEvent() == MENU_DOUBLE_REL) { if(folderMenu.getSelected() == 0) { std::string folder; //Add back 3DS shortcut thing - if(held & KEY_R) + if(held & KEY_R || data::isAppletMode()) 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); diff --git a/src/ui/miscui.cpp b/src/ui/miscui.cpp index e7738b4..4e81b66 100644 --- a/src/ui/miscui.cpp +++ b/src/ui/miscui.cpp @@ -8,7 +8,7 @@ static bool popDraw = false; static std::string popText; -static unsigned popY, popTextX, popState, frameCount, frameHold; +static unsigned popY, popX, popWidth, popState, frameCount, frameHold; enum popStates { @@ -20,8 +20,8 @@ enum popStates //8 static const std::string loadGlyphArray[] = { - "\ue020", "\ue021", "\ue022", "\ue023", "\ue024", - "\ue025", "\ue026", "\ue027" + "\ue020", "\ue021", "\ue022", "\ue023", + "\ue024", "\ue025", "\ue026", "\ue027" }; namespace ui @@ -266,7 +266,7 @@ namespace ui break; } - yes.setText(loadGlyphArray[loadFrame]); + yes.setText(std::string("(Hold) " + loadGlyphArray[loadFrame])); } else if((hold && heldDown) && (up & KEY_A || yes.getEvent() == BUTTON_RELEASED)) { @@ -364,7 +364,8 @@ namespace ui { frameCount = 0; frameHold = frames; - popTextX = 640 - (textGetWidth(mess.c_str(), ui::shared, 24) / 2); + popWidth = textGetWidth(mess.c_str(), ui::shared, 24) + 32; + popX = 640 - (popWidth / 2); popText = mess; popY = 721; @@ -380,7 +381,7 @@ namespace ui switch(popState) { case popRise: - if(popY > 559) + if(popY > 560) popY -= 24; else popState = popShow; @@ -399,7 +400,7 @@ namespace ui break; } - drawTextbox(60, popY, 1160, 64); - drawText(popText.c_str(), frameBuffer, ui::shared, popTextX, popY + 20, 24, ui::txtClr); + drawTextbox(popX, popY, popWidth, 64); + drawText(popText.c_str(), frameBuffer, ui::shared, popX + 16, popY + 20, 24, ui::txtClr); } } diff --git a/src/ui/ttlsel.cpp b/src/ui/ttlsel.cpp index d2fadf1..226a481 100644 --- a/src/ui/ttlsel.cpp +++ b/src/ui/ttlsel.cpp @@ -1,8 +1,6 @@ #include #include -#include - #include "ui.h" #include "uiupdate.h" #include "file.h" @@ -91,7 +89,6 @@ namespace ui { util::makeTitleDir(data::curUser, data::curData); folderMenuPrepare(data::curUser, data::curData); - folderMenuInfo = util::getInfoString(data::curUser, data::curData); mstate = FLD_SEL; } @@ -176,7 +173,9 @@ namespace ui { util::makeTitleDir(data::curUser, data::curData); folderMenuPrepare(data::curUser, data::curData); - folderMenuInfo = util::getInfoString(data::curUser, data::curData); + + //Wanna change this sometime + ui::folderMenuInfo = util::getInfoString(data::curUser, data::curData); mstate = FLD_SEL; } diff --git a/src/ui/usrsel.cpp b/src/ui/usrsel.cpp index 06d0bf9..8564b46 100644 --- a/src/ui/usrsel.cpp +++ b/src/ui/usrsel.cpp @@ -1,5 +1,4 @@ #include -#include #include #include @@ -143,9 +142,8 @@ namespace ui } else if(down & KEY_X || usrNav[2].getEvent() == BUTTON_RELEASED) { - //Just create file so user doesn't have to constantly enable - std::fstream cls(fs::getWorkDir() + "cls.txt", std::ios::out); - cls.close(); + FILE *cls = fopen(std::string(fs::getWorkDir() + "cls.txt").c_str(), "w"); + fclose(cls); clsUserPrep(); mstate = CLS_USR; clsMode = true; diff --git a/src/util.cpp b/src/util.cpp index 941fa7a..de4427e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -10,7 +9,18 @@ #include "file.h" #include "ui.h" -static const char verboten[] = { ',', '/', '\\', '<', '>', ':', '"', '|', '?', '*'}; +static const char verboten[] = { ',', '/', '\\', '<', '>', ':', '"', '|', '?', '*', '™', '©', '®'}; + +static bool isVerboten(uint32_t t) +{ + for(unsigned i = 0; i < 13; i++) + { + if(t == verboten[i]) + return true; + } + + return false; +} //Missing swkbd config funcs for now typedef enum @@ -40,7 +50,7 @@ void swkbdDictWordCreate(dictWord *w, const char *read, const char *word) memcpy(w->word, tmp, 0x30); } -uint32_t replaceIfAccent(uint32_t c) +uint32_t replaceChar(uint32_t c) { switch(c) { @@ -113,17 +123,6 @@ namespace util _path.erase(last + 1, _path.length()); } - bool isVerboten(uint32_t t) - { - for(unsigned i = 0; i < 10; i++) - { - if(t == verboten[i]) - return true; - } - - return false; - } - std::string safeString(const std::string& s) { std::string ret = ""; @@ -134,12 +133,10 @@ namespace util i += untCnt; - tmpChr = replaceIfAccent(tmpChr); + tmpChr = replaceChar(tmpChr); if(isVerboten(tmpChr)) - { ret += ' '; - } else if(tmpChr < 31 || tmpChr > 126) return ""; //return empty string so titledata::init defaults to titleID else @@ -147,8 +144,8 @@ namespace util } //Check for spaces at end - if(ret[ret.length() - 1] == ' ') - ret.erase(ret.end() - 1, ret.end()); + while(ret[ret.length() - 1] == ' ') + ret.erase(ret.length() - 1, 1); return ret; } @@ -247,26 +244,6 @@ namespace util return ret; } - tex *loadDefaultIcon() - { - tex *ret; - - std::fstream iconIn("romfs:/img/icn/icnDefault.png", std::ios::in | std::ios::binary); - iconIn.seekg(0, iconIn.end); - size_t fileSize = iconIn.tellg(); - iconIn.seekg(0xB50, iconIn.beg); - - size_t iconSize = fileSize - 0xB50; - uint8_t *tmpBuff = new uint8_t[iconSize]; - iconIn.read((char *)tmpBuff, iconSize); - iconIn.close(); - - ret = texLoadJPEGMem(tmpBuff, iconSize); - delete[] tmpBuff; - - return ret; - } - tex *createIconGeneric(const char *txt) { tex *ret = texCreate(256, 256);