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:
{
auto& controller = m_sdl_controller.at(event.jaxis.which);
if (m_mode == INPUT_SENSE_GAMEPAD)
controller->handleAxisInputSense(event);
if (controller->handleAxis(event))
input(controller->getEvent());
break;

View File

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

View File

@ -33,6 +33,8 @@ SDLController::SDLController(int device_id)
{
m_irr_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_joystick = NULL;
m_id = -1;
@ -128,6 +130,9 @@ SDLController::SDLController(int device_id)
m_hats = 0;
else
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();
GamepadConfig* cfg = NULL;
@ -177,4 +182,19 @@ SDLController::~SDLController()
m_gamepad->setConnected(false);
} // ~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

View File

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