From 09df747dcc54ce116dec509d8542660cef7a9776 Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 17 Oct 2021 14:31:33 +0200 Subject: [PATCH] Add wpad/kpad support --- source/input/Input.h | 6 ++ source/input/WPADInput.h | 175 +++++++++++++++++++++++++++++++++++++++ source/main.cpp | 23 ++++- 3 files changed, 201 insertions(+), 3 deletions(-) create mode 100644 source/input/WPADInput.h diff --git a/source/input/Input.h b/source/input/Input.h index 14a2192..2e32c62 100644 --- a/source/input/Input.h +++ b/source/input/Input.h @@ -11,6 +11,12 @@ public: //!Destructor virtual ~Input() = default; + void combine(const Input &b) { + data.buttons_d |= b.data.buttons_d; + data.buttons_h |= b.data.buttons_h; + data.buttons_r |= b.data.buttons_r; + } + enum eButtons { BUTTON_NONE = 0x0000, VPAD_TOUCH = 0x80000000, diff --git a/source/input/WPADInput.h b/source/input/WPADInput.h new file mode 100644 index 0000000..6908473 --- /dev/null +++ b/source/input/WPADInput.h @@ -0,0 +1,175 @@ +#pragma once +/**************************************************************************** + * Copyright (C) 2015 Dimok + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ + +#include +#include +#include "Input.h" + +class WPADInput : public Input { +public: + WPADInput(KPADChan channel) { + this->channel = channel; + } + + ~WPADInput() override {} + + uint32_t remapWiiMoteButtons(uint32_t buttons) { + uint32_t conv_buttons = 0; + + if(buttons & WPAD_BUTTON_LEFT) + conv_buttons |= Input::BUTTON_LEFT; + + if(buttons & WPAD_BUTTON_RIGHT) + conv_buttons |= Input::BUTTON_RIGHT; + + if(buttons & WPAD_BUTTON_DOWN) + conv_buttons |= Input::BUTTON_DOWN; + + if(buttons & WPAD_BUTTON_UP) + conv_buttons |= Input::BUTTON_UP; + + if(buttons & WPAD_BUTTON_PLUS) + conv_buttons |= Input::BUTTON_PLUS; + + if(buttons & WPAD_BUTTON_2) + conv_buttons |= Input::BUTTON_2; + + if(buttons & WPAD_BUTTON_1) + conv_buttons |= Input::BUTTON_1; + + if(buttons & WPAD_BUTTON_B) + conv_buttons |= Input::BUTTON_B; + + if(buttons & WPAD_BUTTON_A) + conv_buttons |= Input::BUTTON_A; + + if(buttons & WPAD_BUTTON_MINUS) + conv_buttons |= Input::BUTTON_MINUS; + + if(buttons & WPAD_BUTTON_Z) + conv_buttons |= Input::BUTTON_Z; + + if(buttons & WPAD_BUTTON_C) + conv_buttons |= Input::BUTTON_C; + + if(buttons & WPAD_BUTTON_HOME) + conv_buttons |= Input::BUTTON_HOME; + + return conv_buttons; + } + + uint32_t remapClassicButtons(uint32_t buttons) { + uint32_t conv_buttons = 0; + + if(buttons & WPAD_CLASSIC_BUTTON_LEFT) + conv_buttons |= Input::BUTTON_LEFT; + + if(buttons & WPAD_CLASSIC_BUTTON_RIGHT) + conv_buttons |= Input::BUTTON_RIGHT; + + if(buttons & WPAD_CLASSIC_BUTTON_DOWN) + conv_buttons |= Input::BUTTON_DOWN; + + if(buttons & WPAD_CLASSIC_BUTTON_UP) + conv_buttons |= Input::BUTTON_UP; + + if(buttons & WPAD_CLASSIC_BUTTON_PLUS) + conv_buttons |= Input::BUTTON_PLUS; + + if(buttons & WPAD_CLASSIC_BUTTON_X) + conv_buttons |= Input::BUTTON_X; + + if(buttons & WPAD_CLASSIC_BUTTON_Y) + conv_buttons |= Input::BUTTON_Y; + + if(buttons & WPAD_CLASSIC_BUTTON_B) + conv_buttons |= Input::BUTTON_B; + + if(buttons & WPAD_CLASSIC_BUTTON_A) + conv_buttons |= Input::BUTTON_A; + + if(buttons & WPAD_CLASSIC_BUTTON_MINUS) + conv_buttons |= Input::BUTTON_MINUS; + + if(buttons & WPAD_CLASSIC_BUTTON_HOME) + conv_buttons |= Input::BUTTON_HOME; + + if(buttons & WPAD_CLASSIC_BUTTON_ZR) + conv_buttons |= Input::BUTTON_ZR; + + if(buttons & WPAD_CLASSIC_BUTTON_ZL) + conv_buttons |= Input::BUTTON_ZL; + + if(buttons & WPAD_CLASSIC_BUTTON_R) + conv_buttons |= Input::BUTTON_R; + + if(buttons & WPAD_CLASSIC_BUTTON_L) + conv_buttons |= Input::BUTTON_L; + + return conv_buttons; + } + + bool update(int32_t width, int32_t height) { + WPADExtensionType type; + if (WPADProbe(channel, &type) != 0) { + return false; + } + + KPADRead(channel, &kpad, 1); + + if(kpad.extensionType == WPAD_EXT_CORE || kpad.extensionType == WPAD_EXT_NUNCHUK) { + data.buttons_r = remapWiiMoteButtons(kpad.release); + data.buttons_h = remapWiiMoteButtons(kpad.hold); + data.buttons_d = remapWiiMoteButtons(kpad.trigger); + } else { + data.buttons_r = remapClassicButtons(kpad.classic.release); + data.buttons_h = remapClassicButtons(kpad.classic.hold); + data.buttons_d = remapClassicButtons(kpad.classic.trigger); + } + + data.validPointer = (kpad.posValid == 1 || kpad.posValid == 2) && + (kpad.pos.x >= -1.0f && kpad.pos.x <= 1.0f) && + (kpad.pos.y >= -1.0f && kpad.pos.y <= 1.0f); + + //! calculate the screen offsets if pointer is valid else leave old value + if(data.validPointer) { + data.x = (width >> 1) * kpad.pos.x; + data.y = (height >> 1) * (-kpad.pos.y); + + if(kpad.angle.y > 0.0f) { + data.pointerAngle = (-kpad.angle.x + 1.0f) * 0.5f * 180.0f; + } else { + data.pointerAngle = (kpad.angle.x + 1.0f) * 0.5f * 180.0f - 180.0f; + } + } + + return true; + } + + static void init() { + KPADInit(); + WPADEnableURCC(1); + } + + static void close() { + } + +private: + KPADStatus kpad{}; + KPADChan channel; +}; \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index bf8b31b..4120a6e 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -8,12 +8,15 @@ #include #include #include +#include +#include #include "utils/logger.h" #include "utils/WiiUScreen.h" #include "input/VPADInput.h" #include "MainApplicationState.h" + void initIOSUHax(); void deInitIOSUHax(); @@ -44,8 +47,12 @@ int main(int argc, char **argv) { DEBUG_FUNCTION_LINE("%s:", ntfs_mounts[i].name); } + WPADInput::init(); + main_loop(); + WPADInput::close(); + if (ntfs_mounts != nullptr) { int i = 0; for (i = 0; i < ntfs_mount_count; i++) { @@ -70,7 +77,13 @@ int main(int argc, char **argv) { void main_loop() { DEBUG_FUNCTION_LINE("Creating state"); std::unique_ptr state = std::make_unique(); - VPadInput input; + VPadInput vpadInput; + WPADInput wpadInputs[4] = { + WPAD_CHAN_0, + WPAD_CHAN_1, + WPAD_CHAN_2, + WPAD_CHAN_3 + }; if (gFSAfd < 0 || !sIosuhaxMount) { // state.setError(MainApplicationState::eErrorState::ERROR_IOSUHAX_FAILED); @@ -79,8 +92,12 @@ void main_loop() { DEBUG_FUNCTION_LINE("Entering main loop"); while (WHBProcIsRunning()) { - input.update(1280, 720); - state->update(&input); + vpadInput.update(1280, 720); + for (auto & wpadInput : wpadInputs) { + wpadInput.update(1280, 720); + vpadInput.combine(wpadInput); + } + state->update(&vpadInput); state->render(); } }