|
|
|
|
@ -10,103 +10,159 @@ namespace devilution {
|
|
|
|
|
|
|
|
|
|
std::vector<Joystick> Joystick::joysticks_; |
|
|
|
|
|
|
|
|
|
ControllerButton Joystick::ToControllerButton(const SDL_Event &event) |
|
|
|
|
StaticVector<ControllerButtonEvent, 4> Joystick::ToControllerButtonEvents(const SDL_Event &event) |
|
|
|
|
{ |
|
|
|
|
switch (event.type) { |
|
|
|
|
case SDL_JOYBUTTONDOWN: |
|
|
|
|
case SDL_JOYBUTTONUP: |
|
|
|
|
case SDL_JOYBUTTONUP: { |
|
|
|
|
bool up = (event.jbutton.state == SDL_RELEASED); |
|
|
|
|
switch (event.jbutton.button) { |
|
|
|
|
#ifdef JOY_BUTTON_A |
|
|
|
|
case JOY_BUTTON_A: |
|
|
|
|
return ControllerButton_BUTTON_A; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_A, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_B |
|
|
|
|
case JOY_BUTTON_B: |
|
|
|
|
return ControllerButton_BUTTON_B; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_B, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_X |
|
|
|
|
case JOY_BUTTON_X: |
|
|
|
|
return ControllerButton_BUTTON_X; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_X, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_Y |
|
|
|
|
case JOY_BUTTON_Y: |
|
|
|
|
return ControllerButton_BUTTON_Y; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_Y, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_LEFTSTICK |
|
|
|
|
case JOY_BUTTON_LEFTSTICK: |
|
|
|
|
return ControllerButton_BUTTON_LEFTSTICK; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_LEFTSTICK, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_RIGHTSTICK |
|
|
|
|
case JOY_BUTTON_RIGHTSTICK: |
|
|
|
|
return ControllerButton_BUTTON_RIGHTSTICK; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_RIGHTSTICK, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_LEFTSHOULDER |
|
|
|
|
case JOY_BUTTON_LEFTSHOULDER: |
|
|
|
|
return ControllerButton_BUTTON_LEFTSHOULDER; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_LEFTSHOULDER, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_RIGHTSHOULDER |
|
|
|
|
case JOY_BUTTON_RIGHTSHOULDER: |
|
|
|
|
return ControllerButton_BUTTON_RIGHTSHOULDER; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_RIGHTSHOULDER, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_TRIGGERLEFT |
|
|
|
|
case JOY_BUTTON_TRIGGERLEFT: |
|
|
|
|
return ControllerButton_AXIS_TRIGGERLEFT; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_AXIS_TRIGGERLEFT, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_TRIGGERRIGHT |
|
|
|
|
case JOY_BUTTON_TRIGGERRIGHT: |
|
|
|
|
return ControllerButton_AXIS_TRIGGERRIGHT; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_AXIS_TRIGGERRIGHT, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_START |
|
|
|
|
case JOY_BUTTON_START: |
|
|
|
|
return ControllerButton_BUTTON_START; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_START, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_BACK |
|
|
|
|
case JOY_BUTTON_BACK: |
|
|
|
|
return ControllerButton_BUTTON_BACK; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_BACK, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_DPAD_LEFT |
|
|
|
|
case JOY_BUTTON_DPAD_LEFT: |
|
|
|
|
return ControllerButton_BUTTON_DPAD_LEFT; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_DPAD_LEFT, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_DPAD_UP |
|
|
|
|
case JOY_BUTTON_DPAD_UP: |
|
|
|
|
return ControllerButton_BUTTON_DPAD_UP; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_DPAD_UP, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_DPAD_RIGHT |
|
|
|
|
case JOY_BUTTON_DPAD_RIGHT: |
|
|
|
|
return ControllerButton_BUTTON_DPAD_RIGHT; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_DPAD_RIGHT, up } }; |
|
|
|
|
#endif |
|
|
|
|
#ifdef JOY_BUTTON_DPAD_DOWN |
|
|
|
|
case JOY_BUTTON_DPAD_DOWN: |
|
|
|
|
return ControllerButton_BUTTON_DPAD_DOWN; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_BUTTON_DPAD_DOWN, up } }; |
|
|
|
|
#endif |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_IGNORE, up } }; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case SDL_JOYHATMOTION: |
|
|
|
|
} |
|
|
|
|
case SDL_JOYHATMOTION: { |
|
|
|
|
Joystick *joystick = Get(event); |
|
|
|
|
if (joystick == nullptr) |
|
|
|
|
return { ControllerButtonEvent { ControllerButton_IGNORE, false } }; |
|
|
|
|
joystick->UpdateHatState(event.jhat); |
|
|
|
|
return joystick->GetHatEvents(); |
|
|
|
|
} |
|
|
|
|
case SDL_JOYAXISMOTION: |
|
|
|
|
case SDL_JOYBALLMOTION: |
|
|
|
|
// ProcessAxisMotion() requires a ControllerButtonEvent parameter
|
|
|
|
|
// so provide one here using ControllerButton_NONE
|
|
|
|
|
return { ControllerButtonEvent { ControllerButton_NONE, false } }; |
|
|
|
|
default: |
|
|
|
|
return {}; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
StaticVector<ControllerButtonEvent, 4> Joystick::GetHatEvents() |
|
|
|
|
{ |
|
|
|
|
StaticVector<ControllerButtonEvent, 4> hatEvents; |
|
|
|
|
if (hatState_[0].didStateChange) |
|
|
|
|
hatEvents.emplace_back(ControllerButton_BUTTON_DPAD_UP, !hatState_[0].pressed); |
|
|
|
|
if (hatState_[1].didStateChange) |
|
|
|
|
hatEvents.emplace_back(ControllerButton_BUTTON_DPAD_DOWN, !hatState_[1].pressed); |
|
|
|
|
if (hatState_[2].didStateChange) |
|
|
|
|
hatEvents.emplace_back(ControllerButton_BUTTON_DPAD_LEFT, !hatState_[2].pressed); |
|
|
|
|
if (hatState_[3].didStateChange) |
|
|
|
|
hatEvents.emplace_back(ControllerButton_BUTTON_DPAD_RIGHT, !hatState_[3].pressed); |
|
|
|
|
if (hatEvents.size() == 0) |
|
|
|
|
hatEvents.emplace_back(ControllerButton_IGNORE, false); |
|
|
|
|
return hatEvents; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Joystick::UpdateHatState(const SDL_JoyHatEvent &event) |
|
|
|
|
{ |
|
|
|
|
if (lockHatState_) |
|
|
|
|
return; |
|
|
|
|
#if defined(JOY_HAT_DPAD_UP_HAT) && defined(JOY_HAT_DPAD_UP) |
|
|
|
|
if (event.jhat.hat == JOY_HAT_DPAD_UP_HAT && (event.jhat.value & JOY_HAT_DPAD_UP) != 0) |
|
|
|
|
return ControllerButton_BUTTON_DPAD_UP; |
|
|
|
|
if (event.hat == JOY_HAT_DPAD_UP_HAT) { |
|
|
|
|
HatState &hatState = hatState_[0]; |
|
|
|
|
bool pressed = (event.value & JOY_HAT_DPAD_UP) != 0; |
|
|
|
|
hatState.didStateChange = (pressed != hatState.pressed); |
|
|
|
|
hatState.pressed = pressed; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
#if defined(JOY_HAT_DPAD_DOWN_HAT) && defined(JOY_HAT_DPAD_DOWN) |
|
|
|
|
if (event.jhat.hat == JOY_HAT_DPAD_DOWN_HAT && (event.jhat.value & JOY_HAT_DPAD_DOWN) != 0) |
|
|
|
|
return ControllerButton_BUTTON_DPAD_DOWN; |
|
|
|
|
if (event.hat == JOY_HAT_DPAD_DOWN_HAT) { |
|
|
|
|
HatState &hatState = hatState_[1]; |
|
|
|
|
bool pressed = (event.value & JOY_HAT_DPAD_DOWN) != 0; |
|
|
|
|
hatState.didStateChange = (pressed != hatState.pressed); |
|
|
|
|
hatState.pressed = pressed; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
#if defined(JOY_HAT_DPAD_LEFT_HAT) && defined(JOY_HAT_DPAD_LEFT) |
|
|
|
|
if (event.jhat.hat == JOY_HAT_DPAD_LEFT_HAT && (event.jhat.value & JOY_HAT_DPAD_LEFT) != 0) |
|
|
|
|
return ControllerButton_BUTTON_DPAD_LEFT; |
|
|
|
|
if (event.hat == JOY_HAT_DPAD_LEFT_HAT) { |
|
|
|
|
HatState &hatState = hatState_[2]; |
|
|
|
|
bool pressed = (event.value & JOY_HAT_DPAD_LEFT) != 0; |
|
|
|
|
hatState.didStateChange = (pressed != hatState.pressed); |
|
|
|
|
hatState.pressed = pressed; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
#if defined(JOY_HAT_DPAD_RIGHT_HAT) && defined(JOY_HAT_DPAD_RIGHT) |
|
|
|
|
if (event.jhat.hat == JOY_HAT_DPAD_RIGHT_HAT && (event.jhat.value & JOY_HAT_DPAD_RIGHT) != 0) |
|
|
|
|
return ControllerButton_BUTTON_DPAD_RIGHT; |
|
|
|
|
#endif |
|
|
|
|
return ControllerButton_IGNORE; |
|
|
|
|
break; |
|
|
|
|
default: |
|
|
|
|
break; |
|
|
|
|
if (event.hat == JOY_HAT_DPAD_RIGHT_HAT) { |
|
|
|
|
HatState &hatState = hatState_[3]; |
|
|
|
|
bool pressed = (event.value & JOY_HAT_DPAD_RIGHT) != 0; |
|
|
|
|
hatState.didStateChange = (pressed != hatState.pressed); |
|
|
|
|
hatState.pressed = pressed; |
|
|
|
|
} |
|
|
|
|
return ControllerButton_NONE; |
|
|
|
|
#endif |
|
|
|
|
lockHatState_ = true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void Joystick::UnlockHatState() |
|
|
|
|
{ |
|
|
|
|
lockHatState_ = false; |
|
|
|
|
for (HatState &hatState : hatState_) |
|
|
|
|
hatState.didStateChange = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
int Joystick::ToSdlJoyButton(ControllerButton button) |
|
|
|
|
@ -322,9 +378,9 @@ Joystick *Joystick::Get(const SDL_Event &event)
|
|
|
|
|
case SDL_JOYHATMOTION: |
|
|
|
|
case SDL_JOYBUTTONDOWN: |
|
|
|
|
case SDL_JOYBUTTONUP: |
|
|
|
|
return joysticks_.empty() ? NULL : &joysticks_[0]; |
|
|
|
|
return joysticks_.empty() ? nullptr : &joysticks_[0]; |
|
|
|
|
default: |
|
|
|
|
return NULL; |
|
|
|
|
return nullptr; |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|