#include #include #include #include #include #include #include "ui.h" #include "gfx.h" #include "util.h" #include "file.h" //text mode bool ui::textMode = false; //Current menu state int ui::mstate = USR_SEL, ui::prevState = USR_SEL; //pad data? PadState ui::pad; //Theme id ColorSetId ui::thmID; //Info printed on folder menu std::string ui::folderMenuInfo; //UI colors SDL_Color 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. SDL_Texture *ui::cornerTopLeft, *ui::cornerTopRight, *ui::cornerBottomLeft, *ui::cornerBottomRight; //Progress bar covers + dialog box predrawn SDL_Texture *ui::progCovLeft, *ui::progCovRight, *ui::diaBox; //Menu box pieces SDL_Texture *mnuTopLeft, *mnuTopRight, *mnuBotLeft, *mnuBotRight; //Select box + top left icon SDL_Texture *ui::sideBar; static SDL_Texture *icn; //X position of help texts. Calculated to make editing quicker/easier static unsigned userHelpX, titleHelpX, folderHelpX, optHelpX; //Map to associate external string names to unsigned ints for switch case. static std::unordered_map uistrdef = { {"author", 0}, {"userHelp", 1}, {"titleHelp", 2}, {"folderHelp", 3}, {"optHelp", 4}, {"yt", 5}, {"nt", 6}, {"on", 7}, {"off", 8}, {"confirmBlacklist", 9}, {"confirmOverwrite", 10}, {"confirmRestore", 11}, {"confirmDelete", 12}, {"confirmCopy", 13}, {"confirmEraseNand", 14}, {"confirmEraseFolder", 15}, {"confirmHead", 16}, {"copyHead", 17}, {"noSavesFound", 18}, {"advMenu", 19}, {"extMenu", 20}, {"optMenu", 21}, {"optMenuExp", 22}, {"holdingText", 23}, {"errorConnecting", 24}, {"noUpdate", 25}, {"sortType", 26} }; static void loadTrans() { bool transFile = fs::fileExists(fs::getWorkDir() + "trans.txt"); if(!transFile && (data::sysLang == SetLanguage_ENUS || data::langOverride)) return;//Don't bother loading from file. It serves as a translation guide std::string file; if(transFile) file = fs::getWorkDir() + "trans.txt"; else { file = "romfs:/lang/"; switch(data::sysLang) { case SetLanguage_ZHCN: case SetLanguage_ZHHANS: file += "zh-CN.txt"; break; case SetLanguage_ZHTW: case SetLanguage_ZHHANT: file += "zh-TW.txt"; break; default: return; break; } } fs::dataFile lang(file); while(lang.readNextLine(true)) { switch(uistrdef[lang.getName()]) { case 0: ui::author = lang.getNextValueStr(); break; case 1: ui::userHelp = lang.getNextValueStr(); break; case 2: ui::titleHelp = lang.getNextValueStr(); break; case 3: ui::folderHelp = lang.getNextValueStr(); break; case 4: ui::optHelp = lang.getNextValueStr(); break; case 5: ui::yt = lang.getNextValueStr(); break; case 6: ui::nt = lang.getNextValueStr(); break; case 7: ui::on = lang.getNextValueStr(); break; case 8: ui::off = lang.getNextValueStr(); break; case 9: ui::confBlacklist = lang.getNextValueStr(); break; case 10: ui::confOverwrite = lang.getNextValueStr(); break; case 11: ui::confRestore = lang.getNextValueStr(); break; case 12: ui::confDel = lang.getNextValueStr(); break; case 13: ui::confCopy = lang.getNextValueStr(); break; case 14: ui::confEraseNand = lang.getNextValueStr(); break; case 15: ui::confEraseFolder = lang.getNextValueStr(); break; case 16: ui::confirmHead = lang.getNextValueStr(); break; case 17: ui::copyHead = lang.getNextValueStr(); break; case 18: ui::noSavesFound = lang.getNextValueStr(); break; case 19: { int ind = lang.getNextValueInt(); ui::advMenuStr[ind] = lang.getNextValueStr(); } break; case 20: { int ind = lang.getNextValueInt(); ui::exMenuStr[ind] = lang.getNextValueStr(); } break; case 21: { int ind = lang.getNextValueInt(); ui::optMenuStr[ind] = lang.getNextValueStr(); } break; case 22: { int ind = lang.getNextValueInt(); ui::optMenuExp[ind] = lang.getNextValueStr(); } break; case 23: { int ind = lang.getNextValueInt(); ui::holdingText[ind] = lang.getNextValueStr(); } break; case 24: ui::errorConnecting = lang.getNextValueStr(); break; case 25: ui::noUpdate = lang.getNextValueStr(); break; case 26: { int ind = lang.getNextValueInt(); ui::sortString[ind] = lang.getNextValueStr(); } break; default: ui::showMessage("*Translation File Error:*", "On Line: %s\n*%s* is not a known or valid string name.", lang.getLine(), lang.getName()); break; } } } void ui::initTheme() { setsysGetColorSetId(&thmID); switch(thmID) { case ColorSetId_Light: clearClr = {0xEB, 0xEB, 0xEB, 0xFF}; txtCont = {0x00, 0x00, 0x00, 0xFF}; txtDiag = {0xFF, 0xFF, 0xFF, 0xFF}; rectLt = {0xDF, 0xDF, 0xDF, 0xFF}; rectSh = {0xCA, 0xCA, 0xCA, 0xFF}; tboxClr = {0x50, 0x50, 0x50, 0xFF}; divClr = {0x00, 0x00, 0x00, 0xFF}; break; default: case ColorSetId_Dark: //jic thmID = ColorSetId_Dark; clearClr = {0x2D, 0x2D, 0x2D, 0xFF}; txtCont = {0xFF, 0xFF, 0xFF, 0xFF}; txtDiag = {0x00, 0x00, 0x00, 0xFF}; rectLt = {0x50, 0x50, 0x50, 0xFF}; rectSh = {0x20, 0x20, 0x20, 0xFF}; tboxClr = {0xEB, 0xEB, 0xEB, 0xFF}; divClr = {0xFF, 0xFF, 0xFF, 0xFF}; break; } } void ui::init() { mnuTopLeft = gfx::loadImageFile("romfs:/img/fb/menuTopLeft.png"); mnuTopRight = gfx::loadImageFile("romfs:/img/fb/menuTopRight.png"); mnuBotLeft = gfx::loadImageFile("romfs:/img/fb/menuBotLeft.png"); mnuBotRight = gfx::loadImageFile("romfs:/img/fb/menuBotRight.png"); switch(ui::thmID) { case ColorSetId_Light: //Dark corners cornerTopLeft = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerTopLeft.png"); cornerTopRight = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerTopRight.png"); cornerBottomLeft = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerBotLeft.png"); cornerBottomRight = gfx::loadImageFile("romfs:/img/tboxDrk/tboxCornerBotRight.png"); progCovLeft = gfx::loadImageFile("romfs:/img/tboxDrk/progBarCoverLeftDrk.png"); progCovRight = gfx::loadImageFile("romfs:/img/tboxDrk/progBarCoverRightDrk.png"); icn = gfx::loadImageFile("romfs:/img/icn/icnDrk.png"); sideBar = gfx::loadImageFile("romfs:/img/fb/lLight.png"); break; default: //Light corners cornerTopLeft = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerTopLeft.png"); cornerTopRight = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerTopRight.png"); cornerBottomLeft = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerBotLeft.png"); cornerBottomRight = gfx::loadImageFile("romfs:/img/tboxLght/tboxCornerBotRight.png"); progCovLeft = gfx::loadImageFile("romfs:/img/tboxLght/progBarCoverLeftLight.png"); progCovRight = gfx::loadImageFile("romfs:/img/tboxLght/progBarCoverRightLight.png"); icn = gfx::loadImageFile("romfs:/img/icn/icnLght.png"); sideBar = gfx::loadImageFile("romfs:/img/fb/lDark.png"); break; } 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; textUserPrep(); loadTrans(); //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); util::replaceButtonsInString(ui::optMenuExp[3]); util::replaceButtonsInString(ui::optMenuExp[4]); util::replaceButtonsInString(ui::optMenuExp[5]); //Calculate x position of help text userHelpX = 1220 - gfx::getTextWidth(ui::userHelp.c_str(), 18); titleHelpX = 1220 - gfx::getTextWidth(ui::titleHelp.c_str(), 18); folderHelpX = 1220 - gfx::getTextWidth(ui::folderHelp.c_str(), 18); optHelpX = 1220 - gfx::getTextWidth(ui::optHelp.c_str(), 18); //setup pad padConfigureInput(1, HidNpadStyleSet_NpadStandard); padInitializeDefault(&ui::pad); advCopyMenuPrep(); ui::exMenuPrep(); ui::optMenuInit(); } void ui::exit() { SDL_DestroyTexture(cornerTopLeft); SDL_DestroyTexture(cornerTopRight); SDL_DestroyTexture(cornerBottomLeft); SDL_DestroyTexture(cornerBottomRight); SDL_DestroyTexture(progCovLeft); SDL_DestroyTexture(progCovRight); SDL_DestroyTexture(mnuTopLeft); SDL_DestroyTexture(mnuTopRight); SDL_DestroyTexture(mnuBotLeft); SDL_DestroyTexture(mnuBotRight); SDL_DestroyTexture(icn); } void ui::showLoadScreen() { SDL_Texture *icon = gfx::loadImageFile("romfs:/icon.png"); gfx::clear(&ui::clearClr); gfx::texDraw(icon, 512, 226); gfx::drawTextf(18, 1100, 673, &ui::txtCont, "Loading..."); gfx::present(); SDL_DestroyTexture(icon); } void ui::drawUI() { gfx::clear(&ui::clearClr); gfx::texDraw(icn, 66, 27); gfx::drawTextf(24, 130, 38, &ui::txtCont, "JKSV"); gfx::drawLine(&divClr, 30, 88, 1250, 88); gfx::drawLine(&divClr, 30, 648, 1250, 648); //Version / translation author gfx::drawTextf(12, 8, 700, &ui::txtCont, "v. %02d.%02d.%04d", BLD_MON, BLD_DAY, BLD_YEAR); if(author != "NULL") gfx::drawTextf(12, 8, 682, &ui::txtCont, "Translation: %s", author.c_str()); switch(mstate) { case USR_SEL: gfx::drawTextf(18, userHelpX, 673, &ui::txtCont, userHelp.c_str()); ui::drawUserMenu(); break; case TTL_SEL: gfx::drawTextf(18, titleHelpX, 673, &ui::txtCont, titleHelp.c_str()); ui::drawTitleMenu(); break; case FLD_SEL: gfx::texDraw(sideBar, 0, 89); gfx::drawTextf(18, folderHelpX, 673, &ui::txtCont, folderHelp.c_str()); ui::drawFolderMenu(); break; case TXT_USR: gfx::texDraw(sideBar, 0, 89); gfx::drawTextf(18, userHelpX, 673, &ui::txtCont, userHelp.c_str()); ui::drawTextUserMenu(); break; case TXT_TTL: gfx::texDraw(sideBar, 0, 89); gfx::drawTextf(18, titleHelpX, 673, &ui::txtCont, titleHelp.c_str()); ui::drawTextTitleMenu(); break; case TXT_FLD: gfx::texDraw(sideBar, 0, 89); gfx::drawTextf(18, folderHelpX, 673, &ui::txtCont, folderHelp.c_str()); ui::drawTextFolderMenu(); break; case EX_MNU: gfx::texDraw(sideBar, 0, 89); ui::drawExMenu(); break; case OPT_MNU: gfx::texDraw(sideBar, 0, 89); ui::drawOptMenu(); break; case ADV_MDE: gfx::drawRect(&ui::txtCont, 640, 88, 1, 559); drawAdvMode(); break; } } void ui::drawBoundBox(int x, int y, int w, int h, int clrSh) { SDL_Color rectClr; if(ui::thmID == ColorSetId_Light) rectClr = {0xFD, 0xFD, 0xFD, 0xFF}; else rectClr = {0x21, 0x22, 0x21, 0xFF}; gfx::drawRect(&rectClr, x + 4, y + 4, w - 8, h - 8); rectClr = {0x00,(uint8_t)(0x88 + clrSh), (uint8_t)(0xC5 + (clrSh / 2)), 0xFF}; SDL_SetTextureColorMod(mnuTopLeft, rectClr.r, rectClr.g, rectClr.b); SDL_SetTextureColorMod(mnuTopRight, rectClr.r, rectClr.g, rectClr.b); SDL_SetTextureColorMod(mnuBotLeft, rectClr.r, rectClr.g, rectClr.b); SDL_SetTextureColorMod(mnuBotRight, rectClr.r, rectClr.g, rectClr.b); //top gfx::texDraw(mnuTopLeft, x, y); gfx::drawRect(&rectClr, x + 4, y, w - 8, 4); gfx::texDraw(mnuTopRight, (x + w) - 4, y); //mid gfx::drawRect(&rectClr, x, y + 4, 4, h - 8); gfx::drawRect(&rectClr, (x + w) - 4, y + 4, 4, h - 8); //bottom gfx::texDraw(mnuBotLeft, x, (y + h) - 4); gfx::drawRect(&rectClr, x + 4, (y + h) - 4, w - 8, 4); gfx::texDraw(mnuBotRight, (x + w) - 4, (y + h) - 4); } void ui::runApp(const uint64_t& down, const uint64_t& held) { 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; } drawUI(); drawPopup(down); }