#include "input_mapper.h" #include "input_device_group.h" InputMapper::InputMapper() { inputIdentities = std::set>(); newInputIdentities = std::set>(); deprecatedInputIdentities = std::set>(); } void InputMapper::processEvents() { sf::Event event{}; while (Game::getInstance()->window->pollEvent(event)) { switch (event.type) { case sf::Event::KeyPressed: handleKeyPress(event.key); break; case sf::Event::KeyReleased: handleKeyRelease(event.key); break; case sf::Event::Closed: Game::getInstance()->exit(); break; case sf::Event::Resized: break; case sf::Event::JoystickMoved: handleJoystickMovement(event.joystickMove); break; case sf::Event::JoystickConnected: getInputIdentity(InputDeviceGroup::GAMEPAD, event.joystickConnect.joystickId); break; case sf::Event::JoystickDisconnected: deactivateIdentity(getInputIdentity(InputDeviceGroup::GAMEPAD, event.joystickConnect.joystickId)); break; default: break; } } } void InputMapper::handleKeyPress(sf::Event::KeyEvent event) { // Close game on Escape or Q in DEV Mode if (DEVELOPER_MODE && (event.code == sf::Keyboard::Escape || event.code == sf::Keyboard::Q)) { Game::getInstance()->exit(); return; } // Handle directionVector auto feature = KeyFeatures(event.code); if (feature.deviceGroup != InputDeviceGroup::UNKNOWN) { getInputIdentity(feature.deviceGroup)->direction.add(feature.hardDirection); return; } } void InputMapper::handleKeyRelease(sf::Event::KeyEvent event) { auto feature = KeyFeatures(event.code); if (feature.deviceGroup != InputDeviceGroup::UNKNOWN) { getInputIdentity(feature.deviceGroup)->direction.remove(feature.hardDirection); return; } } void InputMapper::handleJoystickMovement(sf::Event::JoystickMoveEvent event) { auto gamepadIdentity = getInputIdentity(InputDeviceGroup::GAMEPAD, event.joystickId); auto value = event.position / 100.f; auto axis = event.axis; // Handle deadzone and joystick drift if (value > -JOYSTICK_DEADZONE && value < JOYSTICK_DEADZONE) { value = 0.f; } if (axis == sf::Joystick::Axis::X) { gamepadIdentity->direction.setX(value); } else if (axis == sf::Joystick::Axis::Y) { value *= -1; // Is inverted gamepadIdentity->direction.setY(value); } } std::shared_ptr InputMapper::getInputIdentity(InputDeviceGroup deviceGroup, unsigned int gamepadId) { if (deviceGroup == InputDeviceGroup::UNKNOWN) { throw std::invalid_argument("InputDeviceGroup cannot be UNKNOWN"); } for (auto &identity: inputIdentities) { // Device group must be matched, and gamepad id if it is a gamepad if (identity->deviceGroup == deviceGroup && (deviceGroup != InputDeviceGroup::GAMEPAD || identity->gamepadId == gamepadId)) { return identity; } } // No identity found, create new auto newIdentity = std::make_shared(deviceGroup, gamepadId); inputIdentities.insert(newIdentity); newInputIdentities.insert(newIdentity); return newIdentity; } void InputMapper::deactivateIdentity(const std::shared_ptr &identity) { LOG(INFO) << "Destroyed input identity [" << magic_enum::enum_name(identity->deviceGroup) << ", gamepad " << identity->gamepadId << "]"; identity->isActive = false; deprecatedInputIdentities.insert(identity); inputIdentities.erase(identity); } std::shared_ptr InputMapper::getInstance() { if (singletonInstance == nullptr) { singletonInstance = std::make_shared(); } return singletonInstance; } std::set> InputMapper::getInputIdentities() { return inputIdentities; } void InputMapper::updateIdentityEvents() { newInputIdentities.clear(); deprecatedInputIdentities.clear(); }