summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerInterface/Touch
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface/Touch')
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.cpp45
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Touch/ButtonManager.h3
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.cpp272
-rw-r--r--Source/Core/InputCommon/ControllerInterface/Touch/InputOverrider.h89
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