diff options
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/Touch')
4 files changed, 361 insertions, 48 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp b/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp index 7b15f92de9..d55284a65a 100644 --- a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp @@ -9,23 +9,11 @@ #include <unordered_map> #include <vector> -#include "Common/Assert.h" #include "Common/FileUtil.h" #include "Common/IniFile.h" #include "Common/StringUtil.h" #include "Common/Thread.h" -#include "Core/Core.h" -#include "Core/HW/GCPad.h" -#include "Core/HW/GCPadEmu.h" -#include "Core/HW/Wiimote.h" -#include "Core/HW/WiimoteEmu/Extension/Classic.h" -#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" -#include "Core/HW/WiimoteEmu/WiimoteEmu.h" - -#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" -#include "InputCommon/ControllerEmu/StickGate.h" - namespace ButtonManager { namespace @@ -700,39 +688,6 @@ float GetAxisValue(int pad_id, ButtonType axis) return value; } -double GetInputRadiusAtAngle(int pad_id, ButtonType stick, double angle) -{ - // To avoid a crash, don't access controllers before they've been initialized by the boot process - if (!Core::IsRunningAndStarted()) - return 0; - - ControllerEmu::ControlGroup* group; - - switch (stick) - { - case STICK_MAIN: - group = Pad::GetGroup(pad_id, PadGroup::MainStick); - break; - case STICK_C: - group = Pad::GetGroup(pad_id, PadGroup::CStick); - break; - case NUNCHUK_STICK: - group = Wiimote::GetNunchukGroup(pad_id, WiimoteEmu::NunchukGroup::Stick); - break; - case CLASSIC_STICK_LEFT: - group = Wiimote::GetClassicGroup(pad_id, WiimoteEmu::ClassicGroup::LeftStick); - break; - case CLASSIC_STICK_RIGHT: - group = Wiimote::GetClassicGroup(pad_id, WiimoteEmu::ClassicGroup::RightStick); - break; - default: - ASSERT(false); - return 0; - } - - return static_cast<ControllerEmu::ReshapableInput*>(group)->GetInputRadiusAtAngle(angle); -} - bool GamepadEvent(const std::string& dev, int button, int action) { auto it = m_controllers.find(dev); diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h b/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h index 136d15915f..08c4349c84 100644 --- a/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h +++ b/Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h @@ -272,9 +272,6 @@ void Init(const std::string&); bool GetButtonPressed(int pad_id, ButtonType button); float GetAxisValue(int pad_id, ButtonType axis); -// emu_pad_id is numbered 0 to 3 for both GC pads and Wiimotes -double GetInputRadiusAtAngle(int emu_pad_id, ButtonType stick, double angle); - bool GamepadEvent(const std::string& dev, int button, int action); void GamepadAxisEvent(const std::string& dev, int axis, float value); diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.cpp b/Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.cpp new file mode 100644 index 0000000000..9ddbaffcd6 --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.cpp @@ -0,0 +1,272 @@ +// Copyright 2021 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "InputCommon/ControllerInterface/Touch/InputOverrider.h" + +#include <array> +#include <map> +#include <optional> +#include <string> +#include <string_view> +#include <utility> + +#include "Common/Assert.h" + +#include "Core/HW/GCPad.h" +#include "Core/HW/GCPadEmu.h" +#include "Core/HW/Wiimote.h" +#include "Core/HW/WiimoteEmu/Extension/Classic.h" +#include "Core/HW/WiimoteEmu/Extension/Nunchuk.h" +#include "Core/HW/WiimoteEmu/WiimoteEmu.h" + +#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h" +#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/ControllerEmu.h" +#include "InputCommon/ControllerEmu/StickGate.h" +#include "InputCommon/ControllerInterface/CoreDevice.h" +#include "InputCommon/InputConfig.h" + +namespace ciface::Touch +{ +namespace +{ +struct InputState +{ + ControlState normal_state = 0; + ControlState override_state = 0; + bool overriding = false; +}; + +using ControlsMap = std::map<std::pair<std::string_view, std::string_view>, ControlID>; +using StateArray = std::array<InputState, ControlID::NUMBER_OF_CONTROLS>; + +std::array<StateArray, 4> s_state_arrays; + +const ControlsMap s_gcpad_controls_map = {{ + {{GCPad::BUTTONS_GROUP, GCPad::A_BUTTON}, ControlID::GCPAD_A_BUTTON}, + {{GCPad::BUTTONS_GROUP, GCPad::B_BUTTON}, ControlID::GCPAD_B_BUTTON}, + {{GCPad::BUTTONS_GROUP, GCPad::X_BUTTON}, ControlID::GCPAD_X_BUTTON}, + {{GCPad::BUTTONS_GROUP, GCPad::Y_BUTTON}, ControlID::GCPAD_Y_BUTTON}, + {{GCPad::BUTTONS_GROUP, GCPad::Z_BUTTON}, ControlID::GCPAD_Z_BUTTON}, + {{GCPad::BUTTONS_GROUP, GCPad::START_BUTTON}, ControlID::GCPAD_START_BUTTON}, + {{GCPad::DPAD_GROUP, DIRECTION_UP}, ControlID::GCPAD_DPAD_UP}, + {{GCPad::DPAD_GROUP, DIRECTION_DOWN}, ControlID::GCPAD_DPAD_DOWN}, + {{GCPad::DPAD_GROUP, DIRECTION_LEFT}, ControlID::GCPAD_DPAD_LEFT}, + {{GCPad::DPAD_GROUP, DIRECTION_RIGHT}, ControlID::GCPAD_DPAD_RIGHT}, + {{GCPad::TRIGGERS_GROUP, GCPad::L_DIGITAL}, ControlID::GCPAD_L_DIGITAL}, + {{GCPad::TRIGGERS_GROUP, GCPad::R_DIGITAL}, ControlID::GCPAD_R_DIGITAL}, + {{GCPad::TRIGGERS_GROUP, GCPad::L_ANALOG}, ControlID::GCPAD_L_ANALOG}, + {{GCPad::TRIGGERS_GROUP, GCPad::R_ANALOG}, ControlID::GCPAD_R_ANALOG}, + {{GCPad::MAIN_STICK_GROUP, ControllerEmu::ReshapableInput::X_INPUT_OVERRIDE}, + ControlID::GCPAD_MAIN_STICK_X}, + {{GCPad::MAIN_STICK_GROUP, ControllerEmu::ReshapableInput::Y_INPUT_OVERRIDE}, + ControlID::GCPAD_MAIN_STICK_Y}, + {{GCPad::C_STICK_GROUP, ControllerEmu::ReshapableInput::X_INPUT_OVERRIDE}, + ControlID::GCPAD_C_STICK_X}, + {{GCPad::C_STICK_GROUP, ControllerEmu::ReshapableInput::Y_INPUT_OVERRIDE}, + ControlID::GCPAD_C_STICK_Y}, +}}; + +const ControlsMap s_wiimote_controls_map = {{ + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::A_BUTTON}, + ControlID::WIIMOTE_A_BUTTON}, + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::B_BUTTON}, + ControlID::WIIMOTE_B_BUTTON}, + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::ONE_BUTTON}, + ControlID::WIIMOTE_ONE_BUTTON}, + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::TWO_BUTTON}, + ControlID::WIIMOTE_TWO_BUTTON}, + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::PLUS_BUTTON}, + ControlID::WIIMOTE_PLUS_BUTTON}, + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::MINUS_BUTTON}, + ControlID::WIIMOTE_MINUS_BUTTON}, + {{WiimoteEmu::Wiimote::BUTTONS_GROUP, WiimoteEmu::Wiimote::HOME_BUTTON}, + ControlID::WIIMOTE_HOME_BUTTON}, + {{WiimoteEmu::Wiimote::DPAD_GROUP, DIRECTION_UP}, ControlID::WIIMOTE_DPAD_UP}, + {{WiimoteEmu::Wiimote::DPAD_GROUP, DIRECTION_DOWN}, ControlID::WIIMOTE_DPAD_DOWN}, + {{WiimoteEmu::Wiimote::DPAD_GROUP, DIRECTION_LEFT}, ControlID::WIIMOTE_DPAD_LEFT}, + {{WiimoteEmu::Wiimote::DPAD_GROUP, DIRECTION_RIGHT}, ControlID::WIIMOTE_DPAD_RIGHT}, + {{WiimoteEmu::Wiimote::IR_GROUP, ControllerEmu::ReshapableInput::X_INPUT_OVERRIDE}, + ControlID::WIIMOTE_IR_X}, + {{WiimoteEmu::Wiimote::IR_GROUP, ControllerEmu::ReshapableInput::Y_INPUT_OVERRIDE}, + ControlID::WIIMOTE_IR_Y}, +}}; + +const ControlsMap s_nunchuk_controls_map = {{ + {{WiimoteEmu::Nunchuk::BUTTONS_GROUP, WiimoteEmu::Nunchuk::C_BUTTON}, + ControlID::NUNCHUK_C_BUTTON}, + {{WiimoteEmu::Nunchuk::BUTTONS_GROUP, WiimoteEmu::Nunchuk::Z_BUTTON}, + ControlID::NUNCHUK_Z_BUTTON}, + {{WiimoteEmu::Nunchuk::STICK_GROUP, ControllerEmu::ReshapableInput::X_INPUT_OVERRIDE}, + ControlID::NUNCHUK_STICK_X}, + {{WiimoteEmu::Nunchuk::STICK_GROUP, ControllerEmu::ReshapableInput::Y_INPUT_OVERRIDE}, + ControlID::NUNCHUK_STICK_Y}, +}}; + +const ControlsMap s_classic_controls_map = {{ + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::A_BUTTON}, + ControlID::CLASSIC_A_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::B_BUTTON}, + ControlID::CLASSIC_B_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::X_BUTTON}, + ControlID::CLASSIC_X_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::Y_BUTTON}, + ControlID::CLASSIC_Y_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::ZL_BUTTON}, + ControlID::CLASSIC_ZL_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::ZR_BUTTON}, + ControlID::CLASSIC_ZR_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::PLUS_BUTTON}, + ControlID::CLASSIC_PLUS_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::MINUS_BUTTON}, + ControlID::CLASSIC_MINUS_BUTTON}, + {{WiimoteEmu::Classic::BUTTONS_GROUP, WiimoteEmu::Classic::HOME_BUTTON}, + ControlID::CLASSIC_HOME_BUTTON}, + {{WiimoteEmu::Classic::DPAD_GROUP, DIRECTION_UP}, ControlID::CLASSIC_DPAD_UP}, + {{WiimoteEmu::Classic::DPAD_GROUP, DIRECTION_DOWN}, ControlID::CLASSIC_DPAD_DOWN}, + {{WiimoteEmu::Classic::DPAD_GROUP, DIRECTION_LEFT}, ControlID::CLASSIC_DPAD_LEFT}, + {{WiimoteEmu::Classic::DPAD_GROUP, DIRECTION_RIGHT}, ControlID::CLASSIC_DPAD_RIGHT}, + {{WiimoteEmu::Classic::TRIGGERS_GROUP, WiimoteEmu::Classic::L_DIGITAL}, + ControlID::CLASSIC_L_DIGITAL}, + {{WiimoteEmu::Classic::TRIGGERS_GROUP, WiimoteEmu::Classic::R_DIGITAL}, + ControlID::CLASSIC_R_DIGITAL}, + {{WiimoteEmu::Classic::TRIGGERS_GROUP, WiimoteEmu::Classic::L_ANALOG}, + ControlID::CLASSIC_L_ANALOG}, + {{WiimoteEmu::Classic::TRIGGERS_GROUP, WiimoteEmu::Classic::R_ANALOG}, + ControlID::CLASSIC_R_ANALOG}, + {{WiimoteEmu::Classic::LEFT_STICK_GROUP, ControllerEmu::ReshapableInput::X_INPUT_OVERRIDE}, + ControlID::CLASSIC_LEFT_STICK_X}, + {{WiimoteEmu::Classic::LEFT_STICK_GROUP, ControllerEmu::ReshapableInput::Y_INPUT_OVERRIDE}, + ControlID::CLASSIC_LEFT_STICK_Y}, + {{WiimoteEmu::Classic::RIGHT_STICK_GROUP, ControllerEmu::ReshapableInput::X_INPUT_OVERRIDE}, + ControlID::CLASSIC_RIGHT_STICK_X}, + {{WiimoteEmu::Classic::RIGHT_STICK_GROUP, ControllerEmu::ReshapableInput::Y_INPUT_OVERRIDE}, + ControlID::CLASSIC_RIGHT_STICK_Y}, +}}; + +ControllerEmu::InputOverrideFunction GetInputOverrideFunction(const ControlsMap& controls_map, + size_t i) +{ + StateArray& state_array = s_state_arrays[i]; + + return [&](std::string_view group_name, std::string_view control_name, + ControlState controller_state) -> std::optional<ControlState> { + const auto it = controls_map.find(std::make_pair(group_name, control_name)); + if (it == controls_map.end()) + return std::nullopt; + + const ControlID control = it->second; + InputState& input_state = state_array[control]; + if (input_state.normal_state != controller_state) + { + input_state.normal_state = controller_state; + input_state.overriding = false; + } + + return input_state.overriding ? std::make_optional(input_state.override_state) : std::nullopt; + }; +} + +} // namespace + +void RegisterGameCubeInputOverrider(int controller_index) +{ + Pad::GetConfig() + ->GetController(controller_index) + ->SetInputOverrideFunction(GetInputOverrideFunction(s_gcpad_controls_map, controller_index)); +} + +void RegisterWiiInputOverrider(int controller_index) +{ + auto* wiimote = + static_cast<WiimoteEmu::Wiimote*>(Wiimote::GetConfig()->GetController(controller_index)); + + wiimote->SetInputOverrideFunction( + GetInputOverrideFunction(s_wiimote_controls_map, controller_index)); + + auto& attachments = static_cast<ControllerEmu::Attachments*>( + wiimote->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Attachments)) + ->GetAttachmentList(); + + attachments[WiimoteEmu::ExtensionNumber::NUNCHUK]->SetInputOverrideFunction( + GetInputOverrideFunction(s_nunchuk_controls_map, controller_index)); + attachments[WiimoteEmu::ExtensionNumber::CLASSIC]->SetInputOverrideFunction( + GetInputOverrideFunction(s_classic_controls_map, controller_index)); +} + +void UnregisterGameCubeInputOverrider(int controller_index) +{ + Pad::GetConfig()->GetController(controller_index)->ClearInputOverrideFunction(); + + for (size_t i = ControlID::FIRST_GC_CONTROL; i <= ControlID::LAST_GC_CONTROL; ++i) + s_state_arrays[controller_index][i].overriding = false; +} + +void UnregisterWiiInputOverrider(int controller_index) +{ + auto* wiimote = + static_cast<WiimoteEmu::Wiimote*>(Wiimote::GetConfig()->GetController(controller_index)); + + wiimote->ClearInputOverrideFunction(); + + auto& attachments = static_cast<ControllerEmu::Attachments*>( + wiimote->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Attachments)) + ->GetAttachmentList(); + + attachments[WiimoteEmu::ExtensionNumber::NUNCHUK]->ClearInputOverrideFunction(); + attachments[WiimoteEmu::ExtensionNumber::CLASSIC]->ClearInputOverrideFunction(); + + for (size_t i = ControlID::FIRST_WII_CONTROL; i <= ControlID::LAST_WII_CONTROL; ++i) + s_state_arrays[controller_index][i].overriding = false; +} + +void SetControlState(int controller_index, ControlID control, double state) +{ + InputState& input_state = s_state_arrays[controller_index][control]; + + input_state.override_state = state; + input_state.overriding = true; +} + +void ClearControlState(int controller_index, ControlID control) +{ + InputState& input_state = s_state_arrays[controller_index][control]; + + input_state.overriding = false; +} + +double GetGateRadiusAtAngle(int controller_index, ControlID stick, double angle) +{ + ControllerEmu::ControlGroup* group; + + switch (stick) + { + case ControlID::GCPAD_MAIN_STICK_X: + case ControlID::GCPAD_MAIN_STICK_Y: + group = Pad::GetGroup(controller_index, PadGroup::MainStick); + break; + case ControlID::GCPAD_C_STICK_X: + case ControlID::GCPAD_C_STICK_Y: + group = Pad::GetGroup(controller_index, PadGroup::CStick); + break; + case ControlID::NUNCHUK_STICK_X: + case ControlID::NUNCHUK_STICK_Y: + group = Wiimote::GetNunchukGroup(controller_index, WiimoteEmu::NunchukGroup::Stick); + break; + case ControlID::CLASSIC_LEFT_STICK_X: + case ControlID::CLASSIC_LEFT_STICK_Y: + group = Wiimote::GetClassicGroup(controller_index, WiimoteEmu::ClassicGroup::LeftStick); + break; + case ControlID::CLASSIC_RIGHT_STICK_X: + case ControlID::CLASSIC_RIGHT_STICK_Y: + group = Wiimote::GetClassicGroup(controller_index, WiimoteEmu::ClassicGroup::RightStick); + break; + default: + ASSERT(false); + return 0; + } + + return static_cast<ControllerEmu::ReshapableInput*>(group)->GetGateRadiusAtAngle(angle); +} +} // namespace ciface::Touch diff --git a/Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.h b/Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.h new file mode 100644 index 0000000000..6217b44d4e --- /dev/null +++ b/Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.h @@ -0,0 +1,89 @@ +// Copyright 2021 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +namespace ciface::Touch +{ +enum ControlID +{ + GCPAD_A_BUTTON = 0, + GCPAD_B_BUTTON = 1, + GCPAD_X_BUTTON = 2, + GCPAD_Y_BUTTON = 3, + GCPAD_Z_BUTTON = 4, + GCPAD_START_BUTTON = 5, + GCPAD_DPAD_UP = 6, + GCPAD_DPAD_DOWN = 7, + GCPAD_DPAD_LEFT = 8, + GCPAD_DPAD_RIGHT = 9, + GCPAD_L_DIGITAL = 10, + GCPAD_R_DIGITAL = 11, + GCPAD_L_ANALOG = 12, + GCPAD_R_ANALOG = 13, + GCPAD_MAIN_STICK_X = 14, + GCPAD_MAIN_STICK_Y = 15, + GCPAD_C_STICK_X = 16, + GCPAD_C_STICK_Y = 17, + + WIIMOTE_A_BUTTON = 18, + WIIMOTE_B_BUTTON = 19, + WIIMOTE_ONE_BUTTON = 20, + WIIMOTE_TWO_BUTTON = 21, + WIIMOTE_PLUS_BUTTON = 22, + WIIMOTE_MINUS_BUTTON = 23, + WIIMOTE_HOME_BUTTON = 24, + WIIMOTE_DPAD_UP = 25, + WIIMOTE_DPAD_DOWN = 26, + WIIMOTE_DPAD_LEFT = 27, + WIIMOTE_DPAD_RIGHT = 28, + WIIMOTE_IR_X = 29, + WIIMOTE_IR_Y = 30, + + NUNCHUK_C_BUTTON = 31, + NUNCHUK_Z_BUTTON = 32, + NUNCHUK_STICK_X = 33, + NUNCHUK_STICK_Y = 34, + + CLASSIC_A_BUTTON = 35, + CLASSIC_B_BUTTON = 36, + CLASSIC_X_BUTTON = 37, + CLASSIC_Y_BUTTON = 38, + CLASSIC_ZL_BUTTON = 39, + CLASSIC_ZR_BUTTON = 40, + CLASSIC_PLUS_BUTTON = 41, + CLASSIC_MINUS_BUTTON = 42, + CLASSIC_HOME_BUTTON = 43, + CLASSIC_DPAD_UP = 44, + CLASSIC_DPAD_DOWN = 45, + CLASSIC_DPAD_LEFT = 46, + CLASSIC_DPAD_RIGHT = 47, + CLASSIC_L_DIGITAL = 48, + CLASSIC_R_DIGITAL = 49, + CLASSIC_L_ANALOG = 50, + CLASSIC_R_ANALOG = 51, + CLASSIC_LEFT_STICK_X = 52, + CLASSIC_LEFT_STICK_Y = 53, + CLASSIC_RIGHT_STICK_X = 54, + CLASSIC_RIGHT_STICK_Y = 55, + + NUMBER_OF_CONTROLS, + + FIRST_GC_CONTROL = GCPAD_A_BUTTON, + LAST_GC_CONTROL = GCPAD_C_STICK_Y, + FIRST_WII_CONTROL = WIIMOTE_A_BUTTON, + LAST_WII_CONTROL = CLASSIC_RIGHT_STICK_Y, + +}; +void RegisterGameCubeInputOverrider(int controller_index); +void RegisterWiiInputOverrider(int controller_index); +void UnregisterGameCubeInputOverrider(int controller_index); +void UnregisterWiiInputOverrider(int controller_index); + +void SetControlState(int controller_index, ControlID control, double state); +void ClearControlState(int controller_index, ControlID control); + +// Angle is in radians and should be non-negative +double GetGateRadiusAtAngle(int controller_index, ControlID stick, double angle); +} // namespace ciface::Touch |
