bool confirm(int confirmButton, const char *fmt, ...) { char s[512]; memset(s, 0, 512); va_list args; va_start(args, fmt); vsprintf(s, fmt, args); va_end(args); while (aptMainLoop()) { hidScanInput(); u32 key = hidKeysDown(); if (key & BIT(confirmButton)) { return true; } else if (key) { return false; } drawBg(); gfxDrawText(GFX_TOP, GFX_LEFT, &fontDefault, s, MENU_MIN_X + 16, MENU_MIN_Y + 16); gfxDrawText(GFX_TOP, GFX_LEFT, &fontDefault, "Press any key to cancel...", MENU_MIN_X + 16, MENU_MIN_Y + 64); gfxDrawTextf(GFX_TOP, GFX_LEFT, &fontDefault, MENU_MIN_X + 16, MENU_MIN_Y + 84, "Press (%s) to confirm...", get_button(confirmButton)); gfxSwap(); } }
int menu_boot() { time_t start, end, elapsed; int boot_index = config->index; hidScanInput(); if (config->timeout < 0 || hidKeysHeld() & BIT(config->recovery)) { // disable autoboot timer = false; } else if (config->timeout == 0 && config->count > boot_index) { // autoboot return autoBootFix(boot_index); } time(&start); while (aptMainLoop()) { hidScanInput(); u32 kDown = hidKeysDown(); if (timer) { time(&end); elapsed = end - start; if (elapsed >= config->timeout && config->count > boot_index) { return autoBootFix(boot_index); } } if (kDown & KEY_DOWN) { timer = false; boot_index++; if (boot_index > config->count) boot_index = 0; } if (kDown & KEY_UP) { timer = false; boot_index--; if (boot_index < 0) boot_index = config->count; } if (kDown & KEY_A) { timer = false; if (boot_index == config->count) { if (menu_more() == 0) { break; } } else { if (load(config->entries[boot_index].path, config->entries[boot_index].offset) == 0) { break; } } } if (kDown & KEY_X) { timer = false; if (boot_index != config->count) { if (confirm(3, "Delete boot entry: \"%s\" ?\n", config->entries[boot_index].title)) { configRemoveEntry(boot_index); boot_index--; } } } gfxClear(); if (!timer) { gfxDrawText(GFX_TOP, GFX_LEFT, &fontTitle, "*** Grub for CTR beta ***", 120, 20); } else { gfxDrawTextf(GFX_TOP, GFX_LEFT, &fontTitle, 100, 20, "*** Booting %s in %i ***", config->entries[boot_index].title, config->timeout - elapsed); } int minX = 16, maxX = 400 - 16; int minY = 32, maxY = 240 - 8; drawRect(GFX_TOP, GFX_LEFT, minX, minY, maxX, maxY, 0xFF, 0xFF, 0xFF); minY += 20; int i; for (i = 0; i < config->count; i++) { if (i >= config->count) break; if (i == boot_index) { gfxDrawRectangle(GFX_TOP, GFX_LEFT, (u8[]) {0xDC, 0xDC, 0xDC}, minX + 4, minY + (16 * i), maxX - 23, 15); gfxDrawTextf(GFX_TOP, GFX_LEFT, &fontSelected, minX + 6, minY + (16 * i), "%s", config->entries[i].title); gfxDrawText(GFX_BOTTOM, GFX_LEFT, &fontTitle, "Informations", minX + 6, 20); gfxDrawTextf(GFX_BOTTOM, GFX_LEFT, &fontDefault, minX + 12, 40, "Name: %s\nPath: %s\nOffset: 0x%lx\n\n\nPress (A) to launch\nPress (X) to remove entry\n", config->entries[i].title, config->entries[i].path, config->entries[i].offset); } else gfxDrawText(GFX_TOP, GFX_LEFT, &fontDefault, config->entries[i].title, minX + 6, minY + (16 * i)); }
int menu_netloaderarm9(void) { s32 sockfd; struct sockaddr_in sa; s32 clientfd; struct sockaddr_in client_addr; s32 addrlen = sizeof(client_addr); s32 sflags = 0; if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { debug("Err: socket"); return -1; } bzero(&sa, sizeof(sa)); sa.sin_family = AF_INET; sa.sin_port = htons(BRAHMA_NETWORK_PORT); sa.sin_addr.s_addr = gethostid(); if (bind(sockfd, (struct sockaddr *) &sa, sizeof(sa)) != 0) { debug("Err: bind"); close(sockfd); return -1; } if (listen(sockfd, 1) != 0) { debug("Err: listen()"); close(sockfd); return -1; } char msg[256]; sprintf(msg, "NetLoader Active - waiting for arm9\n\n" "IP: %s, Port: %d\n\nPress B to cancel\n", inet_ntoa(sa.sin_addr), BRAHMA_NETWORK_PORT); drawBg(); gfxDrawTextf(GFX_TOP, GFX_LEFT, &fontDefault, MENU_MIN_X + 16, MENU_MIN_Y + 16, msg); gfxSwap(); sflags = fcntl(sockfd, F_GETFL); if (sflags == -1) { debug("Err: fcntl() (1)\n"); close(sockfd); } fcntl(sockfd, F_SETFL, sflags | O_NONBLOCK); while (aptMainLoop()) { hidScanInput(); if (hidKeysDown() & KEY_B) { close(sockfd); return -1; } clientfd = accept(sockfd, (struct sockaddr *) &client_addr, &addrlen); svcSleepThread(100000000); if (clientfd > 0) break; } s32 recvd; u32 total = 0; u8 *arm9_buf = memalign(0x1000, ARM9_PAYLOAD_MAX_SIZE); while ((recvd = recv(clientfd, arm9_buf + total, ARM9_PAYLOAD_MAX_SIZE - total, 0)) != 0) { if (recvd != -1) { total += recvd; drawBg(); gfxDrawTextf(GFX_TOP, GFX_LEFT, &fontDefault, MENU_MIN_X + 16, MENU_MIN_Y + 16, "%i", total); gfxSwap(); } if (total >= ARM9_PAYLOAD_MAX_SIZE) { debug("Err: invalid payload size\n"); close(clientfd); close(sockfd); free(arm9_buf); return -1; } } fcntl(sockfd, F_SETFL, sflags & ~O_NONBLOCK); close(clientfd); close(sockfd); gfxExit(); brahma_init(); if (load_arm9_payload_from_mem(arm9_buf, total) != 1) { debug("Err: Couldn't load arm9 payload...\n"); return -1; } firm_reboot(); brahma_exit(); }