Menus support any controller

This commit is contained in:
Andrew Hawes 2023-06-06 16:32:31 +01:00
parent d7577b15e9
commit a960149e38
4 changed files with 228 additions and 34 deletions

1
.gitignore vendored
View File

@ -2,5 +2,6 @@
*.rpx *.rpx
build/ build/
.idea/ .idea/
.vscode/
cmake-build-debug/ cmake-build-debug/
CMakeLists.txt CMakeLists.txt

View File

@ -38,6 +38,96 @@ std::string string_format(const std::string &format, Args... args) {
return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside
} }
uint32_t remapWiiMoteButtons(uint32_t buttons) {
uint32_t convButtons = 0;
if (buttons & WPAD_BUTTON_LEFT)
convButtons |= VPAD_BUTTON_LEFT;
if (buttons & WPAD_BUTTON_RIGHT)
convButtons |= VPAD_BUTTON_RIGHT;
if (buttons & WPAD_BUTTON_DOWN)
convButtons |= VPAD_BUTTON_DOWN;
if (buttons & WPAD_BUTTON_UP)
convButtons |= VPAD_BUTTON_UP;
if (buttons & WPAD_BUTTON_PLUS)
convButtons |= VPAD_BUTTON_PLUS;
if (buttons & WPAD_BUTTON_2)
convButtons |= VPAD_BUTTON_Y;
if (buttons & WPAD_BUTTON_1)
convButtons |= VPAD_BUTTON_X;
if (buttons & WPAD_BUTTON_B)
convButtons |= VPAD_BUTTON_B;
if (buttons & WPAD_BUTTON_A)
convButtons |= VPAD_BUTTON_A;
if (buttons & WPAD_BUTTON_MINUS)
convButtons |= VPAD_BUTTON_MINUS;
if (buttons & WPAD_BUTTON_HOME)
convButtons |= VPAD_BUTTON_HOME;
return convButtons;
}
uint32_t remapClassicButtons(uint32_t buttons) {
uint32_t convButtons = 0;
if (buttons & WPAD_CLASSIC_BUTTON_LEFT)
convButtons |= VPAD_BUTTON_LEFT;
if (buttons & WPAD_CLASSIC_BUTTON_RIGHT)
convButtons |= VPAD_BUTTON_RIGHT;
if (buttons & WPAD_CLASSIC_BUTTON_DOWN)
convButtons |= VPAD_BUTTON_DOWN;
if (buttons & WPAD_CLASSIC_BUTTON_UP)
convButtons |= VPAD_BUTTON_UP;
if (buttons & WPAD_CLASSIC_BUTTON_PLUS)
convButtons |= VPAD_BUTTON_PLUS;
if (buttons & WPAD_CLASSIC_BUTTON_X)
convButtons |= VPAD_BUTTON_X;
if (buttons & WPAD_CLASSIC_BUTTON_Y)
convButtons |= VPAD_BUTTON_Y;
if (buttons & WPAD_CLASSIC_BUTTON_B)
convButtons |= VPAD_BUTTON_B;
if (buttons & WPAD_CLASSIC_BUTTON_A)
convButtons |= VPAD_BUTTON_A;
if (buttons & WPAD_CLASSIC_BUTTON_MINUS)
convButtons |= VPAD_BUTTON_MINUS;
if (buttons & WPAD_CLASSIC_BUTTON_HOME)
convButtons |= VPAD_BUTTON_HOME;
if (buttons & WPAD_CLASSIC_BUTTON_ZR)
convButtons |= VPAD_BUTTON_ZR;
if (buttons & WPAD_CLASSIC_BUTTON_ZL)
convButtons |= VPAD_BUTTON_ZL;
if (buttons & WPAD_CLASSIC_BUTTON_R)
convButtons |= VPAD_BUTTON_R;
if (buttons & WPAD_CLASSIC_BUTTON_L)
convButtons |= VPAD_BUTTON_L;
return convButtons;
}
int32_t readAutobootOption(std::string &configPath) { int32_t readAutobootOption(std::string &configPath) {
FILE *f = fopen(configPath.c_str(), "r"); FILE *f = fopen(configPath.c_str(), "r");
if (f) { if (f) {
@ -105,11 +195,34 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c
} }
bool redraw = true; bool redraw = true;
while (true) {
VPADStatus vpad{};
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr);
if (vpad.trigger & VPAD_BUTTON_UP) { VPADStatus vpadStatus;
VPADReadError vpadError;
KPADStatus kpadStatus;
KPADError kpadError;
uint32_t buttonsTriggered = 0;
while (true) {
buttonsTriggered = 0;
VPADRead(VPAD_CHAN_0, &vpadStatus, 1, &vpadError);
if (vpadError == VPAD_READ_SUCCESS) {
buttonsTriggered = vpadStatus.trigger;
}
for (int32_t i = 0; i < 4; i++) {
if (KPADReadEx((KPADChan) i, &kpadStatus, 1, &kpadError) > 0) {
if (kpadError == KPAD_ERROR_OK && kpadStatus.extensionType != 0xFF) {
if (kpadStatus.extensionType == WPAD_EXT_CORE || kpadStatus.extensionType == WPAD_EXT_NUNCHUK) {
buttonsTriggered |= remapWiiMoteButtons(kpadStatus.trigger);
} else {
buttonsTriggered |= remapClassicButtons(kpadStatus.classic.trigger);
}
}
}
}
if (buttonsTriggered & VPAD_BUTTON_UP) {
selectedIndex--; selectedIndex--;
if (selectedIndex < 0) { if (selectedIndex < 0) {
@ -117,7 +230,7 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c
} }
redraw = true; redraw = true;
} else if (vpad.trigger & VPAD_BUTTON_DOWN) { } else if (buttonsTriggered & VPAD_BUTTON_DOWN) {
if (!menu.empty()) { if (!menu.empty()) {
selectedIndex++; selectedIndex++;
@ -126,12 +239,12 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c
} }
redraw = true; redraw = true;
} }
} else if (vpad.trigger & VPAD_BUTTON_A) { } else if (buttonsTriggered & VPAD_BUTTON_A) {
break; break;
} else if (vpad.trigger & VPAD_BUTTON_X) { } else if (buttonsTriggered & VPAD_BUTTON_X) {
autobootIndex = -1; autobootIndex = -1;
redraw = true; redraw = true;
} else if (vpad.trigger & VPAD_BUTTON_Y) { } else if (buttonsTriggered & VPAD_BUTTON_Y) {
autobootIndex = selectedIndex; autobootIndex = selectedIndex;
redraw = true; redraw = true;
} }
@ -209,7 +322,6 @@ int32_t handleMenuScreen(std::string &configPath, int32_t autobootOptionInput, c
return selected; return selected;
} }
nn::act::SlotNo handleAccountSelectScreen(const std::vector<std::shared_ptr<AccountInfo>> &data) { nn::act::SlotNo handleAccountSelectScreen(const std::vector<std::shared_ptr<AccountInfo>> &data) {
auto screenBuffer = DrawUtils::InitOSScreen(); auto screenBuffer = DrawUtils::InitOSScreen();
if (!screenBuffer) { if (!screenBuffer) {
@ -226,21 +338,44 @@ nn::act::SlotNo handleAccountSelectScreen(const std::vector<std::shared_ptr<Acco
int32_t selected = 0; int32_t selected = 0;
bool redraw = true; bool redraw = true;
while (true) {
VPADStatus vpad{};
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr);
if (vpad.trigger & VPAD_BUTTON_UP) { VPADStatus vpadStatus;
VPADReadError vpadError;
KPADStatus kpadStatus;
KPADError kpadError;
uint32_t buttonsTriggered = 0;
while (true) {
buttonsTriggered = 0;
VPADRead(VPAD_CHAN_0, &vpadStatus, 1, &vpadError);
if (vpadError == VPAD_READ_SUCCESS) {
buttonsTriggered = vpadStatus.trigger;
}
for (int32_t i = 0; i < 4; i++) {
if (KPADReadEx((KPADChan) i, &kpadStatus, 1, &kpadError) > 0) {
if (kpadError == KPAD_ERROR_OK && kpadStatus.extensionType != 0xFF) {
if (kpadStatus.extensionType == WPAD_EXT_CORE || kpadStatus.extensionType == WPAD_EXT_NUNCHUK) {
buttonsTriggered |= remapWiiMoteButtons(kpadStatus.trigger);
} else {
buttonsTriggered |= remapClassicButtons(kpadStatus.classic.trigger);
}
}
}
}
if (buttonsTriggered & VPAD_BUTTON_UP) {
if (selected > 0) { if (selected > 0) {
selected--; selected--;
redraw = true; redraw = true;
} }
} else if (vpad.trigger & VPAD_BUTTON_DOWN) { } else if (buttonsTriggered & VPAD_BUTTON_DOWN) {
if (selected < (int32_t) data.size() - 1) { if (selected < (int32_t) data.size() - 1) {
selected++; selected++;
redraw = true; redraw = true;
} }
} else if (vpad.trigger & VPAD_BUTTON_A) { } else if (buttonsTriggered & VPAD_BUTTON_A) {
break; break;
} }
@ -392,23 +527,35 @@ void handleUpdateWarningScreen() {
DrawUtils::endDraw(); DrawUtils::endDraw();
while (true) { VPADStatus vpadStatus;
VPADStatus vpad{}; VPADReadError vpadError;
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); KPADStatus kpadStatus;
KPADError kpadError;
uint32_t buttonsTriggered = 0;
while (true) {
buttonsTriggered = 0;
VPADRead(VPAD_CHAN_0, &vpadStatus, 1, &vpadError);
if (vpadError == VPAD_READ_SUCCESS) {
buttonsTriggered = vpadStatus.trigger;
}
KPADStatus kpad;
uint32_t wiimoteButtonsTriggered = 0;
uint32_t classicButtonsTriggered = 0;
for (int32_t i = 0; i < 4; i++) { for (int32_t i = 0; i < 4; i++) {
if (KPADRead((KPADChan) i, &kpad, 1) > 0) { if (KPADReadEx((KPADChan) i, &kpadStatus, 1, &kpadError) > 0) {
wiimoteButtonsTriggered |= kpad.trigger; if (kpadError == KPAD_ERROR_OK && kpadStatus.extensionType != 0xFF) {
classicButtonsTriggered |= kpad.classic.trigger; if (kpadStatus.extensionType == WPAD_EXT_CORE || kpadStatus.extensionType == WPAD_EXT_NUNCHUK) {
buttonsTriggered |= remapWiiMoteButtons(kpadStatus.trigger);
} else {
buttonsTriggered |= remapClassicButtons(kpadStatus.classic.trigger);
}
}
} }
} }
if (vpad.trigger & VPAD_BUTTON_A || wiimoteButtonsTriggered & WPAD_BUTTON_A || classicButtonsTriggered & WPAD_CLASSIC_BUTTON_A) { if (buttonsTriggered & VPAD_BUTTON_A) {
break; break;
} else if (vpad.trigger & VPAD_BUTTON_B || wiimoteButtonsTriggered & WPAD_BUTTON_B || classicButtonsTriggered & WPAD_CLASSIC_BUTTON_B) { } else if (buttonsTriggered & VPAD_BUTTON_B) {
f = fopen(UPDATE_SKIP_PATH, "w"); f = fopen(UPDATE_SKIP_PATH, "w");
if (f) { if (f) {
// It's **really** important to have this text on the stack. // It's **really** important to have this text on the stack.
@ -504,11 +651,34 @@ bool handleDiscInsertScreen(uint64_t expectedTitleId, uint64_t *titleIdToLaunch)
// When an unexpected disc was inserted we need to eject it first. // When an unexpected disc was inserted we need to eject it first.
bool allowDisc = !wrongDiscInserted; bool allowDisc = !wrongDiscInserted;
while (true) {
VPADStatus vpad{};
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr);
if (vpad.trigger & VPAD_BUTTON_A) { VPADStatus vpadStatus;
VPADReadError vpadError;
KPADStatus kpadStatus;
KPADError kpadError;
uint32_t buttonsTriggered = 0;
while (true) {
buttonsTriggered = 0;
VPADRead(VPAD_CHAN_0, &vpadStatus, 1, &vpadError);
if (vpadError == VPAD_READ_SUCCESS) {
buttonsTriggered = vpadStatus.trigger;
}
for (int32_t i = 0; i < 4; i++) {
if (KPADReadEx((KPADChan) i, &kpadStatus, 1, &kpadError) > 0) {
if (kpadError == KPAD_ERROR_OK && kpadStatus.extensionType != 0xFF) {
if (kpadStatus.extensionType == WPAD_EXT_CORE || kpadStatus.extensionType == WPAD_EXT_NUNCHUK) {
buttonsTriggered |= remapWiiMoteButtons(kpadStatus.trigger);
} else {
buttonsTriggered |= remapClassicButtons(kpadStatus.classic.trigger);
}
}
}
}
if (buttonsTriggered & VPAD_BUTTON_A) {
result = false; result = false;
break; break;
} }

View File

@ -27,6 +27,10 @@ enum {
BOOT_OPTION_VWII_HOMEBREW_CHANNEL, BOOT_OPTION_VWII_HOMEBREW_CHANNEL,
}; };
uint32_t remapWiiMoteButtons(uint32_t buttons);
uint32_t remapClassicButtons(uint32_t buttons);
int32_t readAutobootOption(std::string &configPath); int32_t readAutobootOption(std::string &configPath);
void writeAutobootOption(std::string &configPath, int32_t autobootOption); void writeAutobootOption(std::string &configPath, int32_t autobootOption);

View File

@ -52,9 +52,28 @@ int32_t main(int32_t argc, char **argv) {
KPADInit(); KPADInit();
WPADEnableURCC(1); WPADEnableURCC(1);
VPADStatus vpad{}; VPADStatus vpadStatus;
// Buffer vpad read. VPADReadError vpadError;
VPADRead(VPAD_CHAN_0, &vpad, 1, nullptr); KPADStatus kpadStatus;
KPADError kpadError;
uint32_t buttonsHeld = 0;
VPADRead(VPAD_CHAN_0, &vpadStatus, 1, &vpadError);
if (vpadError == VPAD_READ_SUCCESS) {
buttonsHeld = vpadStatus.hold;
}
for (int32_t i = 0; i < 4; i++) {
if (KPADReadEx((KPADChan) i, &kpadStatus, 1, &kpadError) > 0) {
if (kpadError == KPAD_ERROR_OK && kpadStatus.extensionType != 0xFF) {
if (kpadStatus.extensionType == WPAD_EXT_CORE || kpadStatus.extensionType == WPAD_EXT_NUNCHUK) {
buttonsHeld |= remapWiiMoteButtons(kpadStatus.hold);
} else {
buttonsHeld |= remapClassicButtons(kpadStatus.classic.hold);
}
}
}
}
FSAInit(); FSAInit();
auto client = FSAAddClient(nullptr); auto client = FSAAddClient(nullptr);
@ -103,7 +122,7 @@ int32_t main(int32_t argc, char **argv) {
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)) { (buttonsHeld & VPAD_BUTTON_PLUS)) {
bootSelection = handleMenuScreen(configPath, bootSelection, menu); bootSelection = handleMenuScreen(configPath, bootSelection, menu);
} }