Attempt to make the boot menu a bit more robust and flexible

This commit is contained in:
Maschell 2022-08-25 19:54:10 +02:00
parent fca58f95ce
commit 1281dd3c51
3 changed files with 80 additions and 58 deletions

View File

@ -1,28 +1,19 @@
#include "MenuUtils.h" #include "MenuUtils.h"
#include "DrawUtils.h"
#include <cstdint>
#include <cstring>
#include <malloc.h>
#include <string>
#include <vector>
#include <coreinit/debug.h>
#include <coreinit/screen.h>
#include <gx2/state.h>
#include <memory>
#include <nn/act/client_cpp.h>
#include <vpad/input.h>
#include "ACTAccountInfo.h" #include "ACTAccountInfo.h"
#include "DrawUtils.h"
#include "icon_png.h" #include "icon_png.h"
#include "logger.h" #include "logger.h"
#include <coreinit/debug.h>
const char *menu_options[] = { #include <coreinit/screen.h>
"Wii U Menu", #include <cstdint>
"Homebrew Launcher", #include <cstring>
"vWii System Menu", #include <gx2/state.h>
"vWii Homebrew Channel", #include <malloc.h>
}; #include <memory>
#include <nn/act/client_cpp.h>
#include <string>
#include <vector>
#include <vpad/input.h>
const char *autoboot_config_strings[] = { const char *autoboot_config_strings[] = {
"wiiu_menu", "wiiu_menu",
@ -69,7 +60,7 @@ void writeAutobootOption(std::string &configPath, int32_t autobootOption) {
} }
} }
int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, bool showHBL, bool showvHBL) { int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, const std::map<uint32_t, std::string> &menu) {
auto screenBuffer = DrawUtils::InitOSScreen(); auto screenBuffer = DrawUtils::InitOSScreen();
if (!screenBuffer) { if (!screenBuffer) {
OSFatal("Failed to alloc memory for screen"); OSFatal("Failed to alloc memory for screen");
@ -81,44 +72,59 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, b
DrawUtils::initBuffers(screenBuffer, tvBufferSize, (void *) ((uint32_t) screenBuffer + tvBufferSize), drcBufferSize); DrawUtils::initBuffers(screenBuffer, tvBufferSize, (void *) ((uint32_t) screenBuffer + tvBufferSize), drcBufferSize);
DrawUtils::initFont(); DrawUtils::initFont();
uint32_t selected = autobootOptionInput > 0 ? autobootOptionInput : 0; int32_t selectedIndex = autobootOptionInput > 0 ? autobootOptionInput : 0;
int autoboot = autobootOptionInput; int autobootIndex = autobootOptionInput;
bool redraw = true;
// "Convert" id to index
int32_t offset = 0;
for (auto &item : menu) {
if ((uint32_t) selectedIndex == item.first) {
selectedIndex = offset;
break;
}
offset++;
}
if (autobootIndex > 0) {
offset = 0;
for (auto &item : menu) {
if ((uint32_t) autobootIndex == item.first) {
autobootIndex = offset;
break;
}
offset++;
}
}
bool redraw = true;
while (true) { while (true) {
VPADStatus vpad{}; VPADStatus vpad{};
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr);
if (vpad.trigger & VPAD_BUTTON_UP) { if (vpad.trigger & VPAD_BUTTON_UP) {
if (selected > 0) { selectedIndex--;
selected--;
if (!showHBL && selected == BOOT_OPTION_HOMEBREW_LAUNCHER) {
selected--;
}
if (!showvHBL && selected == BOOT_OPTION_VWII_HOMEBREW_CHANNEL) {
selected--;
}
redraw = true; if (selectedIndex < 0) {
selectedIndex = 0;
} }
redraw = true;
} else if (vpad.trigger & VPAD_BUTTON_DOWN) { } else if (vpad.trigger & VPAD_BUTTON_DOWN) {
if (selected < sizeof(menu_options) / sizeof(char *) - 1) { if (!menu.empty()) {
selected++; selectedIndex++;
if (!showHBL && selected == BOOT_OPTION_HOMEBREW_LAUNCHER) {
selected++; if ((uint32_t) selectedIndex >= menu.size()) {
} selectedIndex = menu.size() - 1;
if (!showvHBL && selected == BOOT_OPTION_VWII_HOMEBREW_CHANNEL) {
selected++;
} }
redraw = true; redraw = true;
} }
} else if (vpad.trigger & VPAD_BUTTON_A) { } else if (vpad.trigger & VPAD_BUTTON_A) {
break; break;
} else if (vpad.trigger & VPAD_BUTTON_X) { } else if (vpad.trigger & VPAD_BUTTON_X) {
autoboot = -1; autobootIndex = -1;
redraw = true; redraw = true;
} else if (vpad.trigger & VPAD_BUTTON_Y) { } else if (vpad.trigger & VPAD_BUTTON_Y) {
autoboot = selected; autobootIndex = selectedIndex;
redraw = true; redraw = true;
} }
if (redraw) { if (redraw) {
@ -127,22 +133,18 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, b
// draw buttons // draw buttons
uint32_t index = 8 + 24 + 8 + 4; uint32_t index = 8 + 24 + 8 + 4;
for (uint32_t i = 0; i < sizeof(menu_options) / sizeof(char *); i++) { for (uint32_t i = 0; i < menu.size(); i++) {
if (!showHBL && i == BOOT_OPTION_HOMEBREW_LAUNCHER) { if (i == (uint32_t) selectedIndex) {
continue;
}
if (!showvHBL && i == BOOT_OPTION_VWII_HOMEBREW_CHANNEL) {
continue;
}
if (i == selected) {
DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED); DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 4, COLOR_BORDER_HIGHLIGHTED);
} else { } else {
DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 2, (i == (uint32_t) autoboot) ? COLOR_AUTOBOOT : COLOR_BORDER); DrawUtils::drawRect(16, index, SCREEN_WIDTH - 16 * 2, 44, 2, (i == (uint32_t) autobootIndex) ? COLOR_AUTOBOOT : COLOR_BORDER);
} }
std::string curName = std::next(menu.begin(), i)->second;
DrawUtils::setFontSize(24); DrawUtils::setFontSize(24);
DrawUtils::setFontColor((i == (uint32_t) autoboot) ? COLOR_AUTOBOOT : COLOR_TEXT); DrawUtils::setFontColor((i == (uint32_t) autobootIndex) ? COLOR_AUTOBOOT : COLOR_TEXT);
DrawUtils::print(16 * 2, index + 8 + 24, menu_options[i]); DrawUtils::print(16 * 2, index + 8 + 24, curName.c_str());
index += 42 + 8; index += 42 + 8;
} }
@ -179,6 +181,16 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, b
free(screenBuffer); free(screenBuffer);
int32_t selected = 0;
int32_t autoboot = 0;
// convert index to key
if (selectedIndex > 0 && (uint32_t) selectedIndex < menu.size()) {
selected = std::next(menu.begin(), selectedIndex)->first;
}
if (autobootIndex > 0 && (uint32_t) autobootIndex < menu.size()) {
autoboot = std::next(menu.begin(), autobootIndex)->first;
}
if (autoboot != autobootOptionInput) { if (autoboot != autobootOptionInput) {
writeAutobootOption(configPath, autoboot); writeAutobootOption(configPath, autoboot);
} }

View File

@ -2,6 +2,7 @@
#include "ACTAccountInfo.h" #include "ACTAccountInfo.h"
#include <cstdint> #include <cstdint>
#include <map>
#include <memory> #include <memory>
#include <nn/act.h> #include <nn/act.h>
#include <string> #include <string>
@ -27,6 +28,6 @@ int32_t readAutobootOption(std::string &configPath);
void writeAutobootOption(std::string &configPath, int32_t autobootOption); void writeAutobootOption(std::string &configPath, int32_t autobootOption);
int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, bool showHBL, bool showvHBL); int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, const std::map<uint32_t, std::string> &menu);
nn::act::SlotNo handleAccountSelectScreen(const std::vector<std::shared_ptr<AccountInfo>> &data); nn::act::SlotNo handleAccountSelectScreen(const std::vector<std::shared_ptr<AccountInfo>> &data);

View File

@ -61,12 +61,21 @@ int32_t main(int32_t argc, char **argv) {
VPADStatus vpad{}; VPADStatus vpad{};
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr);
std::map<uint32_t, std::string> menu;
menu[BOOT_OPTION_WII_U_MENU] = "Wii U Menu";
if (showHBL) {
menu[BOOT_OPTION_HOMEBREW_LAUNCHER] = "Homebrew Launcher";
}
menu[BOOT_OPTION_VWII_SYSTEM_MENU] = "vWii System Menu";
if (showvHBL) {
menu[BOOT_OPTION_VWII_HOMEBREW_CHANNEL] = "vWii Homebrew Channel";
}
if ((bootSelection == -1) || if ((bootSelection == -1) ||
(bootSelection == BOOT_OPTION_HOMEBREW_LAUNCHER && !showHBL) || (bootSelection == BOOT_OPTION_HOMEBREW_LAUNCHER && !showHBL) ||
(bootSelection == BOOT_OPTION_VWII_HOMEBREW_CHANNEL && !showvHBL) || (bootSelection == BOOT_OPTION_VWII_HOMEBREW_CHANNEL && !showvHBL) ||
(vpad.hold & VPAD_BUTTON_PLUS)) { (vpad.hold & VPAD_BUTTON_PLUS)) {
bootSelection = handleMenuScreen(configPath, bootSelection, showHBL, showvHBL); bootSelection = handleMenuScreen(configPath, bootSelection, menu);
} }
if (bootSelection >= 0) { if (bootSelection >= 0) {