holesome/src/game/input/input_mapper.cpp

153 lines
4.3 KiB
C++
Raw Normal View History

#include "input_mapper.h"
2023-05-17 23:22:45 +02:00
#include "input_device_group.h"
InputMapper::InputMapper()
{
inputIdentities = std::set<std::shared_ptr<InputIdentity>>();
newInputIdentities = std::set<std::shared_ptr<InputIdentity>>();
deprecatedInputIdentities = std::set<std::shared_ptr<InputIdentity>>();
}
2023-05-08 18:20:55 +02:00
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:
2023-05-09 20:50:50 +02:00
handleKeyRelease(event.key);
break;
case sf::Event::Closed:
Game::getInstance()->exit();
break;
case sf::Event::Resized:
break;
2023-05-16 21:56:55 +02:00
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;
2023-05-09 20:50:50 +02:00
}
}
void InputMapper::handleKeyRelease(sf::Event::KeyEvent event)
{
auto feature = KeyFeatures(event.code);
if (feature.deviceGroup != InputDeviceGroup::UNKNOWN)
2023-05-09 20:50:50 +02:00
{
getInputIdentity(feature.deviceGroup)->direction.remove(feature.hardDirection);
return;
}
}
2023-05-16 21:56:55 +02:00
void InputMapper::handleJoystickMovement(sf::Event::JoystickMoveEvent event)
{
2023-05-17 23:22:45 +02:00
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;
}
2023-05-17 14:41:30 +02:00
if (axis == sf::Joystick::Axis::X)
{
gamepadIdentity->direction.setX(value);
2023-05-17 14:41:30 +02:00
} else if (axis == sf::Joystick::Axis::Y)
{
2023-05-17 14:41:30 +02:00
value *= -1; // Is inverted
gamepadIdentity->direction.setY(value);
}
2023-05-16 21:56:55 +02:00
}
std::shared_ptr<InputIdentity> InputMapper::getInputIdentity(InputDeviceGroup deviceGroup, unsigned int gamepadId)
2023-05-16 21:56:55 +02:00
{
if (deviceGroup == InputDeviceGroup::UNKNOWN)
2023-05-16 21:56:55 +02:00
{
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;
}
2023-05-16 21:56:55 +02:00
}
// No identity found, create new
auto newIdentity = std::make_shared<InputIdentity>(deviceGroup, gamepadId);
inputIdentities.insert(newIdentity);
newInputIdentities.insert(newIdentity);
return newIdentity;
}
void InputMapper::deactivateIdentity(const std::shared_ptr<InputIdentity> &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> InputMapper::getInstance()
{
2023-05-17 14:41:30 +02:00
if (singletonInstance == nullptr)
{
singletonInstance = std::make_shared<InputMapper>();
}
return singletonInstance;
}
std::set<std::shared_ptr<InputIdentity>> InputMapper::getInputIdentities()
{
return inputIdentities;
}
void InputMapper::updateIdentityEvents()
{
newInputIdentities.clear();
deprecatedInputIdentities.clear();
2023-05-16 21:56:55 +02:00
}