#include "mainmenu.h" #include "../gfx/gfx.h" #include "../gfx/gfxutils.h" #include "../gfx/menu.h" #include "tools.h" #include "../hid/hid.h" #include "../fs/menus/explorer.h" #include #include #include "tconf.h" #include "../keys/keys.h" #include "../storage/mountmanager.h" #include "../storage/gptmenu.h" #include "../storage/emummc.h" #include #include "../fs/fsutils.h" #include #include "../utils/utils.h" #include "../config.h" #include "../fs/readers/folderReader.h" #include #include #include "../fs/menus/filemenu.h" #define INCLUDE_BUILTIN_SCRIPTS 1 //#define SCRIPT_ONLY 1 #ifdef INCLUDE_BUILTIN_SCRIPTS #include "../../build/TegraExplorer/script/builtin.h" #define MAX_BUILTIN_MENU_ENTRIES (EMBEDDED_SCRIPTS_LEN * 2) typedef struct { char name[64]; int scriptIndices[EMBEDDED_SCRIPTS_LEN]; int scriptCount; } EmbeddedScriptFolder_t; static void GetScriptDisplayName(const char *fullName, char *out, size_t outSize) { if (!out || outSize == 0) { return; } const char *start = strrchr(fullName, '/'); start = (start) ? start + 1 : fullName; size_t len = 0; while (start[len] && len < outSize - 1) { len++; } if (len >= 3 && start[len - 3] == '.' && start[len - 2] == 't' && start[len - 1] == 'e') { len -= 3; } if (len >= outSize) { len = outSize - 1; } memcpy(out, start, len); out[len] = '\0'; } static void RunEmbeddedScriptIndex(int index) { if (index < 0 || index >= EMBEDDED_SCRIPTS_LEN) { return; } RunScriptString((char*)embedded_scripts_g[index].script, (u32)strlen(embedded_scripts_g[index].script)); } static void ShowEmbeddedFolder(const EmbeddedScriptFolder_t *folder) { if (!folder || folder->scriptCount <= 0) { return; } Vector_t ent = newVec(sizeof(MenuEntry_t), folder->scriptCount + 1); MenuEntry_t backEntry = {.optionUnion = COLORTORGB(COLOR_WHITE), .name = "<- Zurück"}; vecAdd(&ent, backEntry); char displayNames[EMBEDDED_SCRIPTS_LEN][64] = {{0}}; for (int i = 0; i < folder->scriptCount; i++) { int scriptIndex = folder->scriptIndices[i]; if (scriptIndex < 0 || scriptIndex >= EMBEDDED_SCRIPTS_LEN) { continue; } GetScriptDisplayName(embedded_scripts_g[scriptIndex].name, displayNames[i], sizeof(displayNames[i])); MenuEntry_t entry = {.optionUnion = COLORTORGB(COLOR_BLUE), .name = displayNames[i], .icon = 128}; vecAdd(&ent, entry); } int selected = (ent.count > 1) ? 1 : 0; while (1) { gfx_clearscreen(); gfx_printf("%s\n\n", folder->name); int res = newMenu(&ent, selected, 79, 28, ALWAYSREDRAW | ENABLEPAGECOUNT, ent.count - 1); if (res <= 0) { break; } selected = res; int scriptIndex = folder->scriptIndices[res - 1]; RunEmbeddedScriptIndex(scriptIndex); } free(ent.data); } #endif extern hekate_config h_cfg; enum { #ifndef SCRIPT_ONLY MainExit = 0, #else MainExit = 0, #endif MainPowerOff, MainRebootRCM, MainRebootNormal, MainRebootHekate, MainRebootAMS, MainScripts, }; MenuEntry_t mainMenuEntries[] = { #ifndef SCRIPT_ONLY [MainExit] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "-- Exit --"}, #else [MainExit] = {.optionUnion = COLORTORGB(COLOR_WHITE), .name = "-- Exit --"}, #endif [MainPowerOff] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Power off"}, [MainRebootRCM] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to RCM"}, [MainRebootNormal] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot normally"}, [MainRebootHekate] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to bootloader/update.bin"}, [MainRebootAMS] = {.optionUnion = COLORTORGB(COLOR_VIOLET), .name = "Reboot to atmosphere/reboot_payload.bin"}, [MainScripts] = {.optionUnion = COLORTORGB(COLOR_WHITE) | SKIPBIT, .name = "\n-- Scripts --"} }; extern bool sd_mounted; extern int launch_payload(char *path); void RebootToAMS(){ launch_payload("sd:/atmosphere/reboot_payload.bin"); } void RebootToHekate(){ launch_payload("sd:/bootloader/update.bin"); } menuPaths mainMenuPaths[] = { #ifndef SCRIPT_ONLY [MainRebootAMS] = RebootToAMS, [MainRebootHekate] = RebootToHekate, #endif [MainRebootRCM] = reboot_rcm, [MainPowerOff] = power_off, [MainRebootNormal] = reboot_normal, }; void EnterMainMenu(){ int res = 0; while (1){ if (sd_get_card_removed()) sd_unmount(); #ifndef SCRIPT_ONLY mainMenuEntries[MainRebootAMS].hide = (!sd_mounted || !FileExists("sd:/atmosphere/reboot_payload.bin")); mainMenuEntries[MainRebootHekate].hide = (!sd_mounted || !FileExists("sd:/bootloader/update.bin")); mainMenuEntries[MainRebootRCM].hide = h_cfg.t210b01; #endif // -- Scripts -- #ifndef INCLUDE_BUILTIN_SCRIPTS mainMenuEntries[MainScripts].hide = (!sd_mounted || !FileExists("sd:/tegraexplorer/scripts")); #else mainMenuEntries[MainScripts].hide = ((!sd_mounted || !FileExists("sd:/tegraexplorer/scripts")) && !EMBEDDED_SCRIPTS_LEN); #endif Vector_t ent = newVec(sizeof(MenuEntry_t), ARRAY_SIZE(mainMenuEntries)); ent.count = ARRAY_SIZE(mainMenuEntries); memcpy(ent.data, mainMenuEntries, sizeof(MenuEntry_t) * ARRAY_SIZE(mainMenuEntries)); Vector_t scriptFiles = {0}; u8 hasScripts = 0; #ifdef INCLUDE_BUILTIN_SCRIPTS for (int i = 0; i < EMBEDDED_SCRIPTS_LEN; i++){ MenuEntry_t m = {.name = embedded_scripts_g[i].name, .optionUnion = COLORTORGB(COLOR_BLUE), .icon = 128}; vecAdd(&ent, m); } #endif if (sd_mounted && FileExists("sd:/tegraexplorer/scripts")){ scriptFiles = ReadFolder("sd:/tegraexplorer/scripts", &res); if (!res){ if (!scriptFiles.count){ FREE(scriptFiles.data); mainMenuEntries[MainScripts].hide = 1; } else { hasScripts = 1; vecForEach(FSEntry_t*, scriptFile, (&scriptFiles)){ if (!scriptFile->isDir && StrEndsWith(scriptFile->name, ".te")){ MenuEntry_t a = MakeMenuOutFSEntry(*scriptFile); vecAdd(&ent, a); } } if (ent.count == ARRAY_SIZE(mainMenuEntries)){ clearFileVector(&scriptFiles); hasScripts = 0; mainMenuEntries[MainScripts].hide = 1; } } } } gfx_clearscreen(); gfx_putc('\n'); res = newMenu(&ent, res, 79, 30, (ent.count == ARRAY_SIZE(mainMenuEntries)) ? ALWAYSREDRAW : ALWAYSREDRAW | ENABLEPAGECOUNT, ent.count - ARRAY_SIZE(mainMenuEntries)); if (res < MainScripts && mainMenuPaths[res] != NULL) mainMenuPaths[res](); #ifndef INCLUDE_BUILTIN_SCRIPTS else if (hasScripts){ #else else { if (res - ARRAY_SIZE(mainMenuEntries) < EMBEDDED_SCRIPTS_LEN){ char *script = embedded_scripts_g[res - ARRAY_SIZE(mainMenuEntries)].script; RunScriptString(script, strlen(script)); } else { #endif vecDefArray(MenuEntry_t*, entArray, ent); MenuEntry_t entry = entArray[res]; FSEntry_t fsEntry = {.name = entry.name, .sizeUnion = entry.sizeUnion}; RunScript("sd:/tegraexplorer/scripts", fsEntry); #ifdef INCLUDE_BUILTIN_SCRIPTS } #endif } if (hasScripts){ clearFileVector(&scriptFiles); } free(ent.data); } }