From d259811795ce694dfa30e6eca297c1a4c970a773 Mon Sep 17 00:00:00 2001 From: sippeangelo Date: Tue, 13 May 2014 00:55:32 +0200 Subject: [PATCH] Xbox360 controller support --- src/Engine.h | 4 +- src/Events/BindGamepadAxis.h | 21 +++ src/Events/BindGamepadButton.h | 21 +++ src/Events/GamepadAxis.h | 32 ++++ src/Events/GamepadButton.h | 45 +++++ src/GUI/Frame.h | 70 +++---- src/GameWorld.cpp | 47 ++++- src/GameWorld.h | 2 + src/InputManager.cpp | 120 ++++++++++-- src/InputManager.h | 19 +- src/Systems/InputSystem.cpp | 102 +++++++++- src/Systems/InputSystem.h | 18 +- src/Systems/TankSteeringSystem.cpp | 6 +- src/Util/Rectangle.h | 176 +++++++++--------- vs11/Returngeance/Returngeance.vcxproj | 20 +- .../Returngeance/Returngeance.vcxproj.filters | 12 ++ 16 files changed, 552 insertions(+), 163 deletions(-) create mode 100644 src/Events/BindGamepadAxis.h create mode 100644 src/Events/BindGamepadButton.h create mode 100644 src/Events/GamepadAxis.h create mode 100644 src/Events/GamepadButton.h diff --git a/src/Engine.h b/src/Engine.h index 25337c4..c063960 100755 --- a/src/Engine.h +++ b/src/Engine.h @@ -19,7 +19,7 @@ public: m_InputManager = std::make_shared(m_Renderer->GetWindow(), m_EventBroker); - m_UIParent = std::make_shared(m_EventBroker); + //m_UIParent = std::make_shared(m_EventBroker); m_World = std::make_shared(m_EventBroker, m_Renderer); m_World->Initialize(); @@ -46,7 +46,7 @@ private: std::shared_ptr m_EventBroker; std::shared_ptr m_Renderer; std::shared_ptr m_InputManager; - std::shared_ptr m_UIParent; + //std::shared_ptr m_UIParent; // TODO: This should ultimately live in GameFrame std::shared_ptr m_World; diff --git a/src/Events/BindGamepadAxis.h b/src/Events/BindGamepadAxis.h new file mode 100644 index 0000000..b1e16f8 --- /dev/null +++ b/src/Events/BindGamepadAxis.h @@ -0,0 +1,21 @@ +#ifndef Events_BindGamepadAxis_h__ +#define Events_BindGamepadAxis_h__ + +#include + +#include "EventBroker.h" +#include "Events/GamepadAxis.h" + +namespace Events +{ + +struct BindGamepadAxis : Event +{ + Gamepad::Axis Axis; + std::string Command; + float Value; +}; + +} + +#endif // Events_BindGamepadAxis_h__ \ No newline at end of file diff --git a/src/Events/BindGamepadButton.h b/src/Events/BindGamepadButton.h new file mode 100644 index 0000000..72641d8 --- /dev/null +++ b/src/Events/BindGamepadButton.h @@ -0,0 +1,21 @@ +#ifndef Events_BindGamepadButton_h__ +#define Events_BindGamepadButton_h__ + +#include + +#include "EventBroker.h" +#include "Events/GamepadButton.h" + +namespace Events +{ + +struct BindGamepadButton : Event +{ + Gamepad::Button Button; + std::string Command; + float Value; +}; + +} + +#endif // Events_BindGamepadButton_h__ \ No newline at end of file diff --git a/src/Events/GamepadAxis.h b/src/Events/GamepadAxis.h new file mode 100644 index 0000000..3d47767 --- /dev/null +++ b/src/Events/GamepadAxis.h @@ -0,0 +1,32 @@ +#ifndef Events_GamepadAxis_h__ +#define Events_GamepadAxis_h__ + +#include "EventBroker.h" + +namespace Gamepad +{ + enum class Axis + { + LeftX, + LeftY, + RightX, + RightY, + LeftTrigger, + RightTrigger, + LAST = RightTrigger + }; +} + +namespace Events +{ + +struct GamepadAxis : Event +{ + int GamepadID; + Gamepad::Axis Axis; + float Value; +}; + +} + +#endif // Events_GamepadAxis_h__ \ No newline at end of file diff --git a/src/Events/GamepadButton.h b/src/Events/GamepadButton.h new file mode 100644 index 0000000..a99583c --- /dev/null +++ b/src/Events/GamepadButton.h @@ -0,0 +1,45 @@ +#ifndef Events_GamepadButton_h__ +#define Events_GamepadButton_h__ + +#include "EventBroker.h" + +namespace Gamepad +{ + enum class Button + { + Up, + Down, + Left, + Right, + Start, + Back, + LeftThumb, + RightThumb, + LeftShoulder, + RightShoulder, + A, + B, + X, + Y, + LAST = Y + }; +} + +namespace Events +{ + +struct GamepadButtonDown : Event +{ + int GamepadID; + Gamepad::Button Button; +}; + +struct GamepadButtonUp : Event +{ + int GamepadID; + Gamepad::Button Button; +}; + +} + +#endif // Events_GamepadButton_h__ \ No newline at end of file diff --git a/src/GUI/Frame.h b/src/GUI/Frame.h index 19f534a..bb8d51f 100644 --- a/src/GUI/Frame.h +++ b/src/GUI/Frame.h @@ -8,41 +8,41 @@ namespace GUI { - -class Frame : public Rectangle -{ -public: - enum class Anchor - { - Left, - Right, - Top, - Bottom - }; - - // Set up a base frame with an event broker - Frame(std::shared_ptr<::EventBroker> eventBroker) - : EventBroker(eventBroker) - , Rectangle() - { Initialize(); } - // Create a frame as a child - Frame(std::shared_ptr parent) - : Rectangle(static_cast(*parent)) // Clone parent rectangle using copy constructor - { SetParent(parent); Initialize(); } - - virtual void Initialize() { } - std::shared_ptr Parent() const { return m_Parent; } - void SetParent(std::shared_ptr parent) - { - m_Parent = parent; - EventBroker = parent->EventBroker; - } - virtual void Update(double dt) { } - -protected: - std::shared_ptr<::EventBroker> EventBroker; - std::shared_ptr m_Parent; -}; +// +//class Frame : public Rectangle +//{ +//public: +// enum class Anchor +// { +// Left, +// Right, +// Top, +// Bottom +// }; +// +// // Set up a base frame with an event broker +// Frame(std::shared_ptr<::EventBroker> eventBroker) +// : EventBroker(eventBroker) +// , Rectangle() +// { Initialize(); } +// // Create a frame as a child +// Frame(std::shared_ptr parent) +// : Rectangle(static_cast(*parent)) // Clone parent rectangle using copy constructor +// { SetParent(parent); Initialize(); } +// +// virtual void Initialize() { } +// std::shared_ptr Parent() const { return m_Parent; } +// void SetParent(std::shared_ptr parent) +// { +// m_Parent = parent; +// EventBroker = parent->EventBroker; +// } +// virtual void Update(double dt) { } +// +//protected: +// std::shared_ptr<::EventBroker> EventBroker; +// std::shared_ptr m_Parent; +//}; } diff --git a/src/GameWorld.cpp b/src/GameWorld.cpp index 2d743f9..8b29bff 100755 --- a/src/GameWorld.cpp +++ b/src/GameWorld.cpp @@ -8,17 +8,38 @@ void GameWorld::Initialize() m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/Plane.obj"); m_ResourceManager.Preload("Model", "Models/Placeholders/PhysicsTest/ArrowCube.obj"); - BindKey(GLFW_KEY_W, "vertical", -1.f); - BindKey(GLFW_KEY_S, "vertical", 1.f); + BindKey(GLFW_KEY_W, "vertical", 1.f); + BindKey(GLFW_KEY_S, "vertical", -1.f); BindKey(GLFW_KEY_A, "horizontal", -1.f); BindKey(GLFW_KEY_D, "horizontal", 1.f); + BindGamepadAxis(Gamepad::Axis::LeftX, "horizontal", 1.f); + BindGamepadAxis(Gamepad::Axis::RightTrigger, "vertical", 1.f); + BindGamepadAxis(Gamepad::Axis::LeftTrigger, "vertical", -1.f); BindKey(GLFW_KEY_UP, "barrel_rotation", 1.f); BindKey(GLFW_KEY_DOWN, "barrel_rotation", -1.f); - BindKey(GLFW_KEY_LEFT, "tower_rotation", 1.f); - BindKey(GLFW_KEY_RIGHT, "tower_rotation", -1.f); + BindKey(GLFW_KEY_LEFT, "tower_rotation", -1.f); + BindKey(GLFW_KEY_RIGHT, "tower_rotation", 1.f); + BindGamepadAxis(Gamepad::Axis::RightX, "tower_rotation", 1.f); + BindGamepadAxis(Gamepad::Axis::RightY, "barrel_rotation", 1.f); BindKey(GLFW_KEY_SPACE, "handbrake", 1.f); + BindGamepadButton(Gamepad::Button::A, "handbrake", 1.f); + + //BindGamepadButton(Gamepad::Button::Up, "Gamepad::Button::Up", 1.f); + //BindGamepadButton(Gamepad::Button::Down, "Gamepad::Button::Down", 1.f); + //BindGamepadButton(Gamepad::Button::Left, "Gamepad::Button::Left", 1.f); + //BindGamepadButton(Gamepad::Button::Right, "Gamepad::Button::Right", 1.f); + //BindGamepadButton(Gamepad::Button::Start, "Gamepad::Button::Start", 1.f); + //BindGamepadButton(Gamepad::Button::Back, "Gamepad::Button::Back", 1.f); + //BindGamepadButton(Gamepad::Button::LeftThumb, "Gamepad::Button::LeftThumb", 1.f); + //BindGamepadButton(Gamepad::Button::RightThumb, "Gamepad::Button::RightThumb", 1.f); + //BindGamepadButton(Gamepad::Button::LeftShoulder, "Gamepad::Button::LeftShoulder", 1.f); + //BindGamepadButton(Gamepad::Button::RightShoulder, "Gamepad::Button::RightShoulder", 1.f); + //BindGamepadButton(Gamepad::Button::A, "Gamepad::Button::A", 1.f); + //BindGamepadButton(Gamepad::Button::B, "Gamepad::Button::B", 1.f); + //BindGamepadButton(Gamepad::Button::X, "Gamepad::Button::X", 1.f); + //BindGamepadButton(Gamepad::Button::Y, "Gamepad::Button::Y", 1.f); // // BindKey(GLFW_KEY_UP, "vertical", -1.f); // BindKey(GLFW_KEY_DOWN, "vertical", 1.f); @@ -609,3 +630,21 @@ void GameWorld::BindMouseButton(int button, std::string command) e.Command = command; m_EventBroker->Publish(e); } + +void GameWorld::BindGamepadAxis(Gamepad::Axis axis, std::string command, float value) +{ + Events::BindGamepadAxis e; + e.Axis = axis; + e.Command = command; + e.Value = value; + m_EventBroker->Publish(e); +} + +void GameWorld::BindGamepadButton(Gamepad::Button button, std::string command, float value) +{ + Events::BindGamepadButton e; + e.Button = button; + e.Command = command; + e.Value = value; + m_EventBroker->Publish(e); +} diff --git a/src/GameWorld.h b/src/GameWorld.h index 2dfcb96..d258196 100755 --- a/src/GameWorld.h +++ b/src/GameWorld.h @@ -58,6 +58,8 @@ private: void BindKey(int keyCode, std::string command, float value); void BindMouseButton(int button, std::string command); + void BindGamepadAxis(Gamepad::Axis axis, std::string command, float value); + void BindGamepadButton(Gamepad::Button button, std::string command, float value); }; #endif // GameWorld_h__ diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 9f09b1c..fc225ec 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -1,13 +1,14 @@ #include "PrecompiledHeader.h" #include "InputManager.h" +void InputManager::Initialize() +{ + m_LastGamepadAxisState = std::array(); + m_LastGamepadButtonState = std::array(); +} + void InputManager::Update(double dt) { - m_LastKeyState = m_CurrentKeyState; - m_LastMouseState = m_CurrentMouseState; - m_LastMouseX = m_CurrentMouseX; - m_LastMouseY = m_CurrentMouseY; - // Keyboard input for (int i = 0; i <= GLFW_KEY_LAST; ++i) { @@ -19,13 +20,13 @@ void InputManager::Update(double dt) { Events::KeyDown e; e.KeyCode = i; - m_EventBroker->Publish(e); + m_EventBroker->Publish(e); } else { Events::KeyUp e; e.KeyCode = i; - m_EventBroker->Publish(e); + m_EventBroker->Publish(e); } } } @@ -41,18 +42,18 @@ void InputManager::Update(double dt) { Events::MousePress e; e.Button = i; - m_EventBroker->Publish(e); + m_EventBroker->Publish(e); } else { Events::MouseRelease e; e.Button = i; - m_EventBroker->Publish(e); + m_EventBroker->Publish(e); } } } - // Cursor position + // Mouse movement glfwGetCursorPos(m_GLFWWindow, &m_CurrentMouseX, &m_CurrentMouseY); m_CurrentMouseDeltaX = m_CurrentMouseX - m_LastMouseX; m_CurrentMouseDeltaY = m_CurrentMouseY - m_LastMouseY; @@ -64,7 +65,7 @@ void InputManager::Update(double dt) e.Y = m_CurrentMouseY; e.DeltaX = m_CurrentMouseDeltaX; e.DeltaY = m_CurrentMouseDeltaY; - m_EventBroker->Publish(e); + m_EventBroker->Publish(e); } // // Lock mouse while holding LMB @@ -83,4 +84,101 @@ void InputManager::Update(double dt) // { // glfwSetInputMode(m_GLFWWindow, GLFW_CURSOR, GLFW_CURSOR_NORMAL); // } + + // Xbox360 controller + DWORD dwResult; + for (int i = 0; i < XUSER_MAX_COUNT; i++) + { + XINPUT_STATE state = { 0 }; + // Simply get the state of the controller from XInput. + dwResult = XInputGetState(i, &state); + if (dwResult == 0) + { + m_CurrentGamepadAxisState[i][static_cast(Gamepad::Axis::LeftX)] = state.Gamepad.sThumbLX / 32767.f; + m_CurrentGamepadAxisState[i][static_cast(Gamepad::Axis::LeftY)] = state.Gamepad.sThumbLY / 32767.f; + m_CurrentGamepadAxisState[i][static_cast(Gamepad::Axis::RightX)] = state.Gamepad.sThumbRX / 32767.f; + m_CurrentGamepadAxisState[i][static_cast(Gamepad::Axis::RightY)] = state.Gamepad.sThumbRY / 32767.f; + m_CurrentGamepadAxisState[i][static_cast(Gamepad::Axis::LeftTrigger)] = state.Gamepad.bLeftTrigger / 255.f; + m_CurrentGamepadAxisState[i][static_cast(Gamepad::Axis::RightTrigger)] = state.Gamepad.bRightTrigger / 255.f; + PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftX); + PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftY); + PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightX); + PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightY); + PublishGamepadAxisIfChanged(i, Gamepad::Axis::LeftTrigger); + PublishGamepadAxisIfChanged(i, Gamepad::Axis::RightTrigger); + + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Up)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Down)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Left)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Right)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Start)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_START); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Back)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_BACK); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::LeftThumb)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_THUMB); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::RightThumb)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::LeftShoulder)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_LEFT_SHOULDER); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::RightShoulder)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_SHOULDER); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::A)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_A); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::B)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_B); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::X)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_X); + m_CurrentGamepadButtonState[i][static_cast(Gamepad::Button::Y)] = static_cast(state.Gamepad.wButtons & XINPUT_GAMEPAD_Y); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Up); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Down); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Left); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Right); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Start); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Back); + PublishGamepadButtonIfChanged(i, Gamepad::Button::LeftThumb); + PublishGamepadButtonIfChanged(i, Gamepad::Button::RightThumb); + PublishGamepadButtonIfChanged(i, Gamepad::Button::LeftShoulder); + PublishGamepadButtonIfChanged(i, Gamepad::Button::RightShoulder); + PublishGamepadButtonIfChanged(i, Gamepad::Button::A); + PublishGamepadButtonIfChanged(i, Gamepad::Button::B); + PublishGamepadButtonIfChanged(i, Gamepad::Button::X); + PublishGamepadButtonIfChanged(i, Gamepad::Button::Y); + } + } + + m_LastKeyState = m_CurrentKeyState; + m_LastMouseState = m_CurrentMouseState; + m_LastMouseX = m_CurrentMouseX; + m_LastMouseY = m_CurrentMouseY; + m_LastGamepadAxisState = m_CurrentGamepadAxisState; + m_LastGamepadButtonState = m_CurrentGamepadButtonState; +} + +void InputManager::PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis) +{ + float currentValue = m_CurrentGamepadAxisState[gamepadID][static_cast(axis)]; + float lastValue = m_LastGamepadAxisState[gamepadID][static_cast(axis)]; + if (currentValue != lastValue) + { + Events::GamepadAxis e; + e.GamepadID = gamepadID; + e.Axis = axis; + e.Value = currentValue; + m_EventBroker->Publish(e); + } +} + +void InputManager::PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button) +{ + bool currentState = m_CurrentGamepadButtonState[gamepadID][static_cast(button)]; + float lastState = m_LastGamepadButtonState[gamepadID][static_cast(button)]; + if (currentState != lastState) + { + if (currentState == true) + { + Events::GamepadButtonDown e; + e.GamepadID = gamepadID; + e.Button = button; + m_EventBroker->Publish(e); + } + else + { + Events::GamepadButtonUp e; + e.GamepadID = gamepadID; + e.Button = button; + m_EventBroker->Publish(e); + } + } } diff --git a/src/InputManager.h b/src/InputManager.h index 5acaaa2..41d77e7 100644 --- a/src/InputManager.h +++ b/src/InputManager.h @@ -3,12 +3,16 @@ #include +#include + #include "EventBroker.h" #include "Events/KeyDown.h" #include "Events/KeyUp.h" #include "Events/MousePress.h" #include "Events/MouseRelease.h" #include "Events/MouseMove.h" +#include "Events/GamepadAxis.h" +#include "Events/GamepadButton.h" class InputManager { @@ -22,7 +26,10 @@ public: , m_LastMouseState() , m_CurrentMouseX(0), m_CurrentMouseY(0) , m_LastMouseX(0), m_LastMouseY(0) - , m_CurrentMouseDeltaX(0), m_CurrentMouseDeltaY(0) { } + , m_CurrentMouseDeltaX(0), m_CurrentMouseDeltaY(0) + { Initialize(); } + + void Initialize(); void Update(double dt); @@ -34,9 +41,19 @@ private: std::array m_LastKeyState; std::array m_CurrentMouseState; std::array m_LastMouseState; + typedef std::array(Gamepad::Axis::LAST) + 1> GamepadAxisState; + std::array m_CurrentGamepadAxisState; + std::array m_LastGamepadAxisState; + typedef std::array(Gamepad::Button::LAST) + 1> GamepadButtonState; + std::array m_CurrentGamepadButtonState; + std::array m_LastGamepadButtonState; + double m_CurrentMouseX, m_CurrentMouseY; double m_LastMouseX, m_LastMouseY; double m_CurrentMouseDeltaX, m_CurrentMouseDeltaY; + + void PublishGamepadAxisIfChanged(int gamepadID, Gamepad::Axis axis); + void PublishGamepadButtonIfChanged(int gamepadID, Gamepad::Button button); }; #endif // InputManager_h__ diff --git a/src/Systems/InputSystem.cpp b/src/Systems/InputSystem.cpp index 4868213..7c4cde7 100755 --- a/src/Systems/InputSystem.cpp +++ b/src/Systems/InputSystem.cpp @@ -10,12 +10,17 @@ void Systems::InputSystem::RegisterComponents(ComponentFactory* cf) void Systems::InputSystem::Initialize() { // Subscribe to events - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Systems::InputSystem::OnKeyDown) - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::InputSystem::OnKeyUp) - EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Systems::InputSystem::OnMousePress) - EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Systems::InputSystem::OnMouseRelease) - EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &Systems::InputSystem::OnBindKey) - EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &Systems::InputSystem::OnBindMouseButton) + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Systems::InputSystem::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Systems::InputSystem::OnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Systems::InputSystem::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Systems::InputSystem::OnMouseRelease); + EVENT_SUBSCRIBE_MEMBER(m_EGamepadAxis, &Systems::InputSystem::OnGamepadAxis); + EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonDown, &Systems::InputSystem::OnGamepadButtonDown); + EVENT_SUBSCRIBE_MEMBER(m_EGamepadButtonUp, &Systems::InputSystem::OnGamepadButtonUp); + EVENT_SUBSCRIBE_MEMBER(m_EBindKey, &Systems::InputSystem::OnBindKey); + EVENT_SUBSCRIBE_MEMBER(m_EBindMouseButton, &Systems::InputSystem::OnBindMouseButton); + EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadAxis, &Systems::InputSystem::OnBindGamepadAxis); + EVENT_SUBSCRIBE_MEMBER(m_EBindGamepadButton, &Systems::InputSystem::OnBindGamepadButton); } void Systems::InputSystem::Update(double dt) @@ -47,8 +52,8 @@ bool Systems::InputSystem::OnKeyDown(const Events::KeyDown &event) std::string command; float value; std::tie(command, value) = bindingIt->second; - m_KeyBindingValues[command] += value; - PublishCommand(0, command, std::max(-1.f, std::min(m_KeyBindingValues[command], 1.f))); + m_CommandValues[command] += value; + PublishCommand(0, command, std::max(-1.f, std::min(m_CommandValues[command], 1.f))); } return true; @@ -62,8 +67,8 @@ bool Systems::InputSystem::OnKeyUp(const Events::KeyUp &event) std::string command; float value; std::tie(command, value) = bindingIt->second; - m_KeyBindingValues[command] -= value; - PublishCommand(0, command, std::max(-1.f, std::min(m_KeyBindingValues[command], 1.f))); + m_CommandValues[command] -= value; + PublishCommand(0, command, std::max(-1.f, std::min(m_CommandValues[command], 1.f))); } return true; @@ -91,6 +96,51 @@ bool Systems::InputSystem::OnMouseRelease(const Events::MouseRelease &event) return true; } +bool Systems::InputSystem::OnGamepadAxis(const Events::GamepadAxis &event) +{ + auto bindingIt = m_GamepadAxisBindings.find(event.Axis); + if (bindingIt != m_GamepadAxisBindings.end()) + { + std::string command; + float value; + std::tie(command, value) = bindingIt->second; + PublishCommand(event.GamepadID + 1, command, event.Value * value); + } + + return true; +} + +bool Systems::InputSystem::OnGamepadButtonDown(const Events::GamepadButtonDown &event) +{ + auto bindingIt = m_GamepadButtonBindings.find(event.Button); + if (bindingIt != m_GamepadButtonBindings.end()) + { + std::string command; + float value; + std::tie(command, value) = bindingIt->second; + m_CommandValues[command] += value; + PublishCommand(event.GamepadID + 1, command, std::max(-1.f, std::min(m_CommandValues[command], 1.f))); + } + + return true; +} + +bool Systems::InputSystem::OnGamepadButtonUp(const Events::GamepadButtonUp &event) +{ + auto bindingIt = m_GamepadButtonBindings.find(event.Button); + if (bindingIt != m_GamepadButtonBindings.end()) + { + std::string command; + float value; + std::tie(command, value) = bindingIt->second; + m_CommandValues[command] -= value; + PublishCommand(event.GamepadID + 1, command, std::max(-1.f, std::min(m_CommandValues[command], 1.f))); + } + + return true; +} + + bool Systems::InputSystem::OnBindKey(const Events::BindKey &event) { if (event.Command.empty()) @@ -121,6 +171,36 @@ bool Systems::InputSystem::OnBindMouseButton(const Events::BindMouseButton &even return true; } +bool Systems::InputSystem::OnBindGamepadAxis(const Events::BindGamepadAxis &event) +{ + if (event.Command.empty()) + { + m_GamepadAxisBindings.erase(event.Axis); + } + else + { + m_GamepadAxisBindings[event.Axis] = std::make_tuple(event.Command, event.Value); + LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Axis, event.Command.c_str()); + } + + return true; +} + +bool Systems::InputSystem::OnBindGamepadButton(const Events::BindGamepadButton &event) +{ + if (event.Command.empty()) + { + m_GamepadButtonBindings.erase(event.Button); + } + else + { + m_GamepadButtonBindings[event.Button] = std::make_tuple(event.Command, event.Value); + LOG_DEBUG("Input: Bound gamepad axis %i to %s", event.Button, event.Command.c_str()); + } + + return true; +} + void Systems::InputSystem::PublishCommand(int playerID, std::string command, float value) { Events::InputCommand e; @@ -131,3 +211,5 @@ void Systems::InputSystem::PublishCommand(int playerID, std::string command, flo LOG_DEBUG("Input: Published command %s=%f for player %i", e.Command.c_str(), e.Value, playerID); } + + diff --git a/src/Systems/InputSystem.h b/src/Systems/InputSystem.h index b9461a2..ce9a7f3 100755 --- a/src/Systems/InputSystem.h +++ b/src/Systems/InputSystem.h @@ -11,8 +11,12 @@ #include "Events/KeyDown.h" #include "Events/MousePress.h" #include "Events/MouseRelease.h" +#include "Events/GamepadAxis.h" +#include "Events/GamepadButton.h" #include "Events/BindKey.h" #include "Events/BindMouseButton.h" +#include "Events/BindGamepadAxis.h" +#include "Events/BindGamepadButton.h" #include "Events/InputCommand.h" namespace Systems @@ -30,10 +34,12 @@ public: void Update(double dt) override; private: + std::unordered_map m_CommandValues; // command string -> command current value // Input binding tables std::unordered_map> m_KeyBindings; // GLFW_KEY... -> command string & value - std::unordered_map m_KeyBindingValues; // command string -> command value std::unordered_map m_MouseButtonBindings; // GLFW_MOUSE_BUTTON... -> command string + std::unordered_map> m_GamepadAxisBindings; // Gamepad::Axis -> command string & value + std::unordered_map> m_GamepadButtonBindings; // Gamepad::Button -> command string // Input events EventRelay m_EKeyDown; @@ -44,11 +50,21 @@ private: bool OnMousePress(const Events::MousePress &event); EventRelay m_EMouseRelease; bool OnMouseRelease(const Events::MouseRelease &event); + EventRelay m_EGamepadAxis; + bool OnGamepadAxis(const Events::GamepadAxis &event); + EventRelay m_EGamepadButtonDown; + bool OnGamepadButtonDown(const Events::GamepadButtonDown &event); + EventRelay m_EGamepadButtonUp; + bool OnGamepadButtonUp(const Events::GamepadButtonUp &event); // Input binding events EventRelay m_EBindKey; bool OnBindKey(const Events::BindKey &event); EventRelay m_EBindMouseButton; bool OnBindMouseButton(const Events::BindMouseButton &event); + EventRelay m_EBindGamepadAxis; + bool OnBindGamepadAxis(const Events::BindGamepadAxis &event); + EventRelay m_EBindGamepadButton; + bool OnBindGamepadButton(const Events::BindGamepadButton &event); void PublishCommand(int playerID, std::string command, float value); }; diff --git a/src/Systems/TankSteeringSystem.cpp b/src/Systems/TankSteeringSystem.cpp index eee50cc..9d631c8 100644 --- a/src/Systems/TankSteeringSystem.cpp +++ b/src/Systems/TankSteeringSystem.cpp @@ -72,12 +72,12 @@ bool Systems::TankSteeringSystem::TankSteeringInputController::OnCommand(const E } else if (event.Command == "vertical") { - m_Vertical = val; + m_Vertical = -val; } else if (event.Command == "handbrake") { - Handbrake = val; + Handbrake = val > 0; } return true; @@ -88,7 +88,7 @@ bool Systems::TankSteeringSystem::TowerSteeringInputController::OnCommand( const float val = event.Value; if(event.Command == "tower_rotation") { - m_TowerDirection = val; + m_TowerDirection = -val; } else if(event.Command == "barrel_rotation") { diff --git a/src/Util/Rectangle.h b/src/Util/Rectangle.h index 0d0db32..a257855 100644 --- a/src/Util/Rectangle.h +++ b/src/Util/Rectangle.h @@ -3,93 +3,93 @@ #include -struct Rectangle -{ - Rectangle() - : X(0), Y(0), Width(0), Height(0) { } - - Rectangle(int x, int y, int width = 0, int height = 0) - : X(x), Y(y), Width(width), Height(height) { } - - /*Rectangle(const Rectangle &rect) - : X(rect.X), Y(rect.Y), Width(rect.Width), Height(rect.Height) { }*/ - - int X; - int Y; - int Width; - int Height; - - const int& GetLeft() const { return X; } - void SetLeft(int left) - { - Width += X - left; - X = left; - } - int GetRight() const { return X + Width; } - void SetRight(int right) - { - Width = right - X; - } - const int& GetTop() const { return Y; } - void SetTop(int top) - { - Height += Y - top; - Y = top; - } - int GetBottom() const { return Y + Height; } - int SetBottom(int bottom) - { - Height = bottom - Y; - } - - Rectangle& operator+=(const Rectangle &rhs) - { - SetLeft(std::min(GetLeft(), rhs.GetLeft())); - SetRight(std::max(GetRight(), rhs.GetRight())); - SetTop(std::min(GetTop(), rhs.GetTop())); - SetBottom(std::max(GetBottom(), rhs.GetBottom())); - } - - static bool Intersects(const Rectangle &r1, const Rectangle &r2) - { - return !(r2.GetLeft() > r1.GetRight() || r2.GetRight() < r1.GetLeft() || r2.GetTop() > r1.GetBottom() || r2.GetBottom() < r1.GetTop()); - } -}; - -inline bool operator==(const Rectangle &r1, const Rectangle &r2) -{ - return (r1.X == r2.X) && (r1.Y == r2.Y) && (r1.Width == r2.Width) && (r1.Height == r2.Height); -} - -inline bool operator!=(const Rectangle &lhs, const Rectangle &rhs) -{ - return !(lhs == rhs); -} - -inline bool operator<(const Rectangle &lhs, const Rectangle &rhs) -{ - return (lhs.Width < rhs.Width) && (lhs.Height < rhs.Height); -} - -inline bool operator>(const Rectangle &lhs, const Rectangle &rhs) -{ - return rhs < lhs; -} - -inline bool operator<=(const Rectangle &lhs, const Rectangle &rhs) -{ - return !(lhs > rhs); -} - -inline bool operator>=(const Rectangle &lhs, const Rectangle &rhs) -{ - return !(lhs < rhs); -} - -inline Rectangle operator+(Rectangle lhs, const Rectangle &rhs) -{ - lhs += rhs; - return lhs; -} +//struct Rectangle +//{ +// Rectangle() +// : X(0), Y(0), Width(0), Height(0) { } +// +// Rectangle(int x, int y, int width = 0, int height = 0) +// : X(x), Y(y), Width(width), Height(height) { } +// +// /*Rectangle(const Rectangle &rect) +// : X(rect.X), Y(rect.Y), Width(rect.Width), Height(rect.Height) { }*/ +// +// int X; +// int Y; +// int Width; +// int Height; +// +// const int& GetLeft() const { return X; } +// void SetLeft(int left) +// { +// Width += X - left; +// X = left; +// } +// int GetRight() const { return X + Width; } +// void SetRight(int right) +// { +// Width = right - X; +// } +// const int& GetTop() const { return Y; } +// void SetTop(int top) +// { +// Height += Y - top; +// Y = top; +// } +// int GetBottom() const { return Y + Height; } +// int SetBottom(int bottom) +// { +// Height = bottom - Y; +// } +// +// Rectangle& operator+=(const Rectangle &rhs) +// { +// SetLeft(std::min(GetLeft(), rhs.GetLeft())); +// SetRight(std::max(GetRight(), rhs.GetRight())); +// SetTop(std::min(GetTop(), rhs.GetTop())); +// SetBottom(std::max(GetBottom(), rhs.GetBottom())); +// } +// +// static bool Intersects(const Rectangle &r1, const Rectangle &r2) +// { +// return !(r2.GetLeft() > r1.GetRight() || r2.GetRight() < r1.GetLeft() || r2.GetTop() > r1.GetBottom() || r2.GetBottom() < r1.GetTop()); +// } +//}; +// +//inline bool operator==(const Rectangle &r1, const Rectangle &r2) +//{ +// return (r1.X == r2.X) && (r1.Y == r2.Y) && (r1.Width == r2.Width) && (r1.Height == r2.Height); +//} +// +//inline bool operator!=(const Rectangle &lhs, const Rectangle &rhs) +//{ +// return !(lhs == rhs); +//} +// +//inline bool operator<(const Rectangle &lhs, const Rectangle &rhs) +//{ +// return (lhs.Width < rhs.Width) && (lhs.Height < rhs.Height); +//} +// +//inline bool operator>(const Rectangle &lhs, const Rectangle &rhs) +//{ +// return rhs < lhs; +//} +// +//inline bool operator<=(const Rectangle &lhs, const Rectangle &rhs) +//{ +// return !(lhs > rhs); +//} +// +//inline bool operator>=(const Rectangle &lhs, const Rectangle &rhs) +//{ +// return !(lhs < rhs); +//} +// +//inline Rectangle operator+(Rectangle lhs, const Rectangle &rhs) +//{ +// lhs += rhs; +// return lhs; +//} #endif // Util_Rectangle_h__ diff --git a/vs11/Returngeance/Returngeance.vcxproj b/vs11/Returngeance/Returngeance.vcxproj index 9affcba..3ca02eb 100755 --- a/vs11/Returngeance/Returngeance.vcxproj +++ b/vs11/Returngeance/Returngeance.vcxproj @@ -39,21 +39,21 @@ - $(HAVOK_2013_1_0_r1_ROOT)\Source;$(BOOST_1_55_0_ROOT);$(SolutionDir)\..\src;$(SolutionDir)\..\libs;$(SolutionDir)\..\libs\glew-1.10.0\include;$(SolutionDir)\..\libs\glfw-3.0.4\include;$(SolutionDir)\..\libs\glm-0.9.5.3;$(SolutionDir)\..\libs\openal-soft-1.15.1\include;$(SolutionDir)\..\libs\bullet-2.82-r2704\src;$(SolutionDir)\..\libs\SOIL\src;$(IncludePath) - $(HAVOK_2013_1_0_r1_ROOT)\Lib\win32_vs2012_win7\debug_dll;$(BOOST_1_55_0_ROOT)\lib32-msvc-11.0;$(SolutionDir)\..\libs\glew-1.10.0\lib\Debug\Win32;$(SolutionDir)\..\libs\glfw-3.0.4\lib\Debug;$(SolutionDir)\..\libs\openal-soft-1.15.1\lib\Win32\Debug;$(SolutionDir)\..\libs\bullet-2.82-r2704\lib\Debug;$(SolutionDir)\..\libs\SOIL\lib\Debug;$(LibraryPath) + $(HAVOK_2013_1_0_r1_ROOT)\Source;$(BOOST_1_55_0_ROOT);$(SolutionDir)\..\src;$(SolutionDir)\..\libs;$(SolutionDir)\..\libs\glew-1.10.0\include;$(SolutionDir)\..\libs\glfw-3.0.4\include;$(SolutionDir)\..\libs\glm-0.9.5.3;$(SolutionDir)\..\libs\openal-soft-1.15.1\include;$(SolutionDir)\..\libs\bullet-2.82-r2704\src;$(SolutionDir)\..\libs\SOIL\src;$(DXSDK_DIR)\Include;$(IncludePath) + $(HAVOK_2013_1_0_r1_ROOT)\Lib\win32_vs2012_win7\debug_dll;$(BOOST_1_55_0_ROOT)\lib32-msvc-11.0;$(SolutionDir)\..\libs\glew-1.10.0\lib\Debug\Win32;$(SolutionDir)\..\libs\glfw-3.0.4\lib\Debug;$(SolutionDir)\..\libs\openal-soft-1.15.1\lib\Win32\Debug;$(SolutionDir)\..\libs\bullet-2.82-r2704\lib\Debug;$(SolutionDir)\..\libs\SOIL\lib\Debug;$(LibraryPath);$(DXSDK_DIR)\Lib\x86 $(SolutionDir)\..\bin\$(Configuration)\ $(SolutionDir)\..\obj\$(Configuration)\ - $(HAVOK_2013_1_0_r1_ROOT)\Source;$(BOOST_1_55_0_ROOT);$(SolutionDir)\..\src;$(SolutionDir)\..\libs;$(SolutionDir)\..\libs\glew-1.10.0\include;$(SolutionDir)\..\libs\glfw-3.0.4\include;$(SolutionDir)\..\libs\glm-0.9.5.3;$(SolutionDir)\..\libs\openal-soft-1.15.1\include;$(SolutionDir)\..\libs\bullet-2.82-r2704\src;$(SolutionDir)\..\libs\SOIL\src;$(IncludePath) - $(HAVOK_2013_1_0_r1_ROOT)\Lib\win32_vs2012_win7\release_dll;$(BOOST_1_55_0_ROOT)\lib32-msvc-11.0;$(SolutionDir)\..\libs\glfw-3.0.4\lib\Release;$(SolutionDir)\..\libs\glew-1.10.0\lib\Release\Win32;$(SolutionDir)\..\libs\openal-soft-1.15.1\lib\Win32\Release;$(SolutionDir)\..\libs\bullet-2.82-r2704\lib\Release;$(SolutionDir)\..\libs\SOIL\lib\Release;$(LibraryPath) + $(HAVOK_2013_1_0_r1_ROOT)\Source;$(BOOST_1_55_0_ROOT);$(SolutionDir)\..\src;$(SolutionDir)\..\libs;$(SolutionDir)\..\libs\glew-1.10.0\include;$(SolutionDir)\..\libs\glfw-3.0.4\include;$(SolutionDir)\..\libs\glm-0.9.5.3;$(SolutionDir)\..\libs\openal-soft-1.15.1\include;$(SolutionDir)\..\libs\bullet-2.82-r2704\src;$(SolutionDir)\..\libs\SOIL\src;$(DXSDK_DIR)\Include;$(IncludePath) + $(HAVOK_2013_1_0_r1_ROOT)\Lib\win32_vs2012_win7\release_dll;$(BOOST_1_55_0_ROOT)\lib32-msvc-11.0;$(SolutionDir)\..\libs\glfw-3.0.4\lib\Release;$(SolutionDir)\..\libs\glew-1.10.0\lib\Release\Win32;$(SolutionDir)\..\libs\openal-soft-1.15.1\lib\Win32\Release;$(SolutionDir)\..\libs\bullet-2.82-r2704\lib\Release;$(SolutionDir)\..\libs\SOIL\lib\Release;$(LibraryPath);$(DXSDK_DIR)\Lib\x86 $(SolutionDir)\..\bin\$(Configuration)\ $(SolutionDir)\..\obj\$(Configuration)\ Level3 - _WINDOWS;WIN32;_WIN32;_DEBUG;HK_DEBUG;HK_DEBUG_SLOW;_XT_STATICLINK;_CONSOLE;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;HK_CONFIG_SIMD=1;DEBUG;_CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) + _X86_;_WINDOWS;WIN32;_WIN32;_DEBUG;HK_DEBUG;HK_DEBUG_SLOW;_XT_STATICLINK;_CONSOLE;_ALLOW_ITERATOR_DEBUG_LEVEL_MISMATCH;HK_CONFIG_SIMD=1;DEBUG;_CRT_SECURE_NO_WARNINGS;_MBCS;%(PreprocessorDefinitions) Create PrecompiledHeader.h MultiThreadedDebugDLL @@ -65,7 +65,7 @@ true - OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32d.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;hkpVehicle.lib;%(AdditionalDependencies) + OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;XInput9_1_0.lib;glew32d.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;hkpVehicle.lib;%(AdditionalDependencies) /ignore:4221 @@ -80,7 +80,7 @@ true true true - _CRT_SECURE_NO_WARNINGS;_MBCS;HK_CONFIG_SIMD=1;%(PreprocessorDefinitions) + _X86_;_CRT_SECURE_NO_WARNINGS;_MBCS;HK_CONFIG_SIMD=1;%(PreprocessorDefinitions) Create PrecompiledHeader.h StreamingSIMDExtensions2 @@ -89,7 +89,7 @@ true true true - OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;glew32.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;hkpVehicle.lib;%(AdditionalDependencies) + OpenAL32.lib;opengl32.lib;glu32.lib;SOIL.lib;XInput9_1_0.lib;glew32.lib;glfw3.lib;hkBase.lib;hkVisualize.lib;hkInternal.lib;hkSerialize.lib;hkGeometryUtilities.lib;hkcdInternal.lib;hkcdCollide.lib;hkpCollide.lib;hkpConstraint.lib;hkpConstraintSolver.lib;hkpDynamics.lib;hkpInternal.lib;hkpUtilities.lib;hkSceneData.lib;hkpVehicle.lib;%(AdditionalDependencies) @@ -150,8 +150,12 @@ + + + + diff --git a/vs11/Returngeance/Returngeance.vcxproj.filters b/vs11/Returngeance/Returngeance.vcxproj.filters index 0323b51..081f144 100755 --- a/vs11/Returngeance/Returngeance.vcxproj.filters +++ b/vs11/Returngeance/Returngeance.vcxproj.filters @@ -328,6 +328,18 @@ Physics\Components + + Input\Events + + + Input\Events + + + Input\Events + + + Input\Events +