Fix input sensing with SDL2

This commit is contained in:
Benau 2020-04-21 00:30:03 +08:00
parent 189938e179
commit 130be12a64
4 changed files with 35 additions and 6 deletions

View File

@ -133,6 +133,8 @@ void InputManager::update(float dt)
case SDL_JOYAXISMOTION: case SDL_JOYAXISMOTION:
{ {
auto& controller = m_sdl_controller.at(event.jaxis.which); auto& controller = m_sdl_controller.at(event.jaxis.which);
if (m_mode == INPUT_SENSE_GAMEPAD)
controller->handleAxisInputSense(event);
if (controller->handleAxis(event)) if (controller->handleAxis(event))
input(controller->getEvent()); input(controller->getEvent());
break; break;

View File

@ -71,9 +71,6 @@ private:
*/ */
int m_mouse_val_x, m_mouse_val_y; int m_mouse_val_x, m_mouse_val_y;
void dispatchInput(Input::InputType, int deviceID, int btnID,
Input::AxisDirection direction, int value,
bool shift_mask = false);
void handleStaticAction(int id0, int value); void handleStaticAction(int id0, int value);
void inputSensing(Input::InputType type, int deviceID, int btnID, void inputSensing(Input::InputType type, int deviceID, int btnID,
Input::AxisDirection axisDirection, int value); Input::AxisDirection axisDirection, int value);
@ -117,6 +114,10 @@ public:
* re-plugging later with the same ID. */ * re-plugging later with the same ID. */
size_t getGamepadCount() const { return m_sdl_controller.size(); } size_t getGamepadCount() const { return m_sdl_controller.size(); }
#endif #endif
void dispatchInput(Input::InputType, int deviceID, int btnID,
Input::AxisDirection direction, int value,
bool shift_mask = false);
}; };
extern InputManager *input_manager; extern InputManager *input_manager;

View File

@ -33,6 +33,8 @@ SDLController::SDLController(int device_id)
{ {
m_irr_event = {}; m_irr_event = {};
m_irr_event.EventType = irr::EET_JOYSTICK_INPUT_EVENT; m_irr_event.EventType = irr::EET_JOYSTICK_INPUT_EVENT;
memset(m_prev_axes, 0,
irr::SEvent::SJoystickEvent::NUMBER_OF_AXES * sizeof(int16_t));
m_game_controller = NULL; m_game_controller = NULL;
m_joystick = NULL; m_joystick = NULL;
m_id = -1; m_id = -1;
@ -128,6 +130,9 @@ SDLController::SDLController(int device_id)
m_hats = 0; m_hats = 0;
else else
m_buttons += m_hats * 4; m_buttons += m_hats * 4;
// Save previous axes values for input sensing
for (int i = 0; i < m_axes; i++)
m_prev_axes[i] = SDL_JoystickGetAxis(m_joystick, i);
DeviceManager* dm = input_manager->getDeviceManager(); DeviceManager* dm = input_manager->getDeviceManager();
GamepadConfig* cfg = NULL; GamepadConfig* cfg = NULL;
@ -177,4 +182,19 @@ SDLController::~SDLController()
m_gamepad->setConnected(false); m_gamepad->setConnected(false);
} // ~SDLController } // ~SDLController
// ----------------------------------------------------------------------------
/** SDL only sends event when axis moves, so we need to send previously saved
* event for correct input sensing. */
void SDLController::handleAxisInputSense(const SDL_Event& event)
{
int axis_idx = event.jaxis.axis;
if (axis_idx > m_axes)
return;
if (event.jaxis.value == m_prev_axes[axis_idx])
return;
input_manager->dispatchInput(Input::IT_STICKMOTION,
m_irr_event.JoystickEvent.Joystick, axis_idx, Input::AD_NEUTRAL,
m_prev_axes[axis_idx]);
} // handleAxisInputSense
#endif #endif

View File

@ -44,6 +44,8 @@ private:
SDL_JoystickID m_id; SDL_JoystickID m_id;
irr::SEvent m_irr_event; irr::SEvent m_irr_event;
int16_t m_prev_axes[irr::SEvent::SJoystickEvent::NUMBER_OF_AXES];
public: public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
SDLController(int device_id); SDLController(int device_id);
@ -54,12 +56,16 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
SDL_JoystickID getInstanceID() const { return m_id; } SDL_JoystickID getInstanceID() const { return m_id; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void handleAxisInputSense(const SDL_Event& event);
// ------------------------------------------------------------------------
bool handleAxis(const SDL_Event& event) bool handleAxis(const SDL_Event& event)
{ {
if (event.jaxis.axis > m_axes) int axis_idx = event.jaxis.axis;
if (axis_idx > m_axes)
return false; return false;
m_irr_event.JoystickEvent.Axis[event.jaxis.axis] = event.jaxis.value; m_irr_event.JoystickEvent.Axis[axis_idx] = event.jaxis.value;
uint32_t value = 1 << event.jaxis.axis; m_prev_axes[axis_idx] = event.jaxis.value;
uint32_t value = 1 << axis_idx;
m_irr_event.JoystickEvent.AxisChanged = value; m_irr_event.JoystickEvent.AxisChanged = value;
return true; return true;
} // handleAxis } // handleAxis