#include "InputManager.h" #include #define WIN32_LEAN_AND_MEAN #include #include #include class dae::InputManager::KeyboardImpl { public: ~KeyboardImpl() { for (auto& pair : m_KeyboardCommands) { for (auto& pair2 : pair.second) { delete pair2.second; pair2.second = nullptr; } } } void AddKeyboardCommand(unsigned int sceneId, unsigned int keyboardButton, PressType pressType, Command* pCommand) { KeyboardButtonAndPressType keyAndType; keyAndType.first = keyboardButton; keyAndType.second = pressType; m_KeyboardCommands[sceneId][keyAndType] = pCommand; }; bool IsKeyDown(unsigned int keycode) { return IsKeyPressed(keycode) && ((m_PreviousKeyState[keycode]) == 0); } bool IsKeyUp(unsigned int keycode) { return !IsKeyPressed(keycode) && ((m_PreviousKeyState[keycode]) != 0); } bool IsKeyPressed(unsigned int keycode) { return m_KeyState[keycode]; } bool ProcessInput(unsigned int sceneId) { // Keyboard input SDL_Event e; while (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { return false; } } const Uint8* keystate; keystate = SDL_GetKeyboardState(NULL); std::copy(m_KeyState, m_KeyState + SDL_NUM_SCANCODES, m_PreviousKeyState); std::copy(keystate, keystate + SDL_NUM_SCANCODES, m_KeyState); for (const auto& pair : m_KeyboardCommands[sceneId]) { switch (pair.first.second) { case PressType::DOWN: if (IsKeyDown(pair.first.first)) { pair.second->Execute(); } break; case PressType::UP: if (IsKeyUp(pair.first.first)) { pair.second->Execute(); } break; case PressType::HELD: if (IsKeyPressed(pair.first.first)) { pair.second->Execute(); } break; } } return true; } private: std::map> m_KeyboardCommands; uint8_t m_KeyState[MAX_KEYCODES] = {}; uint8_t m_PreviousKeyState[MAX_KEYCODES] = {}; }; class dae::InputManager::ControllersImpl { public: bool ProcessInput(unsigned int sceneId) { // Controllers input for (int i = 0; i < m_NrMaxControllers; ++i) { m_PreviousControllerState[i] = m_ControllerState[i]; XInputGetState(i, &m_ControllerState[i]); } for (int i = 0; i < m_NrMaxControllers; ++i) { for (const auto& pair : m_ControllerCommands[i][sceneId]) { switch (pair.first.second) { case PressType::DOWN: if (IsButtonDown(i, WORD(pair.first.first))) { pair.second->Execute(); } break; case PressType::UP: if (IsButtonUp(i, WORD(pair.first.first))) { pair.second->Execute(); } break; case PressType::HELD: if (IsButtonPressed(i, WORD(pair.first.first))) { pair.second->Execute(); } break; } } } return true; } ~ControllersImpl() { for (int i = 0; i < m_NrMaxControllers; ++i) { for (auto& pair : m_ControllerCommands[i]) { for (auto& pair2 : pair.second) { delete pair2.second; pair2.second = nullptr; } } } } bool IsButtonDown(int controllerId, WORD button) { return IsButtonPressed(controllerId, button) && ((m_PreviousControllerState[controllerId].Gamepad.wButtons & button) == 0); } bool IsButtonUp(int controllerId, WORD button) { return !IsButtonPressed(controllerId, button) && ((m_PreviousControllerState[controllerId].Gamepad.wButtons & button) != 0); } bool IsButtonPressed(int controllerId, WORD button) { return (m_ControllerState[controllerId].Gamepad.wButtons & button) != 0; } float LeftThumbstickX(int controllerId) { int val = m_ControllerState[controllerId].Gamepad.sThumbLX; if (abs(val) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { return 0; } return static_cast(val) / 32767.0f; } float LeftThumbstickY(int controllerId) { int val = m_ControllerState[controllerId].Gamepad.sThumbLY; if (abs(val) < XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) { return 0; } return static_cast(val) / 32767.0f; } float RightThumbstickX(int controllerId) { int val = m_ControllerState[controllerId].Gamepad.sThumbRX; if (abs(val) < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { return 0; } return static_cast(val) / 32767.0f; } float RightThumbstickY(int controllerId) { int val = m_ControllerState[controllerId].Gamepad.sThumbRY; if (abs(val) < XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) { return 0; } return static_cast(val) / 32767.0f; } void AddControllerCommand(unsigned int sceneId, int controllerId, ControllerButton controllerButton, PressType pressType, Command* pCommand) { ControllerButtonAndPressType buttonAndType; buttonAndType.first = controllerButton; buttonAndType.second = pressType; m_ControllerCommands[controllerId][sceneId][buttonAndType] = pCommand; } private: const int m_NrMaxControllers{ 4 }; XINPUT_STATE m_ControllerState[4]{}; XINPUT_STATE m_PreviousControllerState[4]{}; std::map> m_ControllerCommands[4]; const float m_DeadZone = 0.2f; }; void dae::InputManager::AddControllerCommand(unsigned int sceneId, int controllerId, ControllerButton controllerButton, PressType pressType, Command* pCommand) { pControllerImpl->AddControllerCommand(sceneId, controllerId, controllerButton, pressType, pCommand); } void dae::InputManager::AddKeyboardCommand(unsigned int sceneId, unsigned int keyboardButton, PressType pressType, Command* pCommand) { pKeyboardImpl->AddKeyboardCommand(sceneId, keyboardButton, pressType, pCommand); } dae::InputManager::InputManager() { pControllerImpl = new ControllersImpl(); pKeyboardImpl = new KeyboardImpl(); } bool dae::InputManager::ProcessInput(unsigned int sceneId) { // Controller input pControllerImpl->ProcessInput(sceneId); // Keyboard input return pKeyboardImpl->ProcessInput(sceneId); } dae::InputManager::~InputManager() { delete pControllerImpl; pControllerImpl = nullptr; delete pKeyboardImpl; pKeyboardImpl = nullptr; }