Skip to content

Commit

Permalink
Remove manual joystick polling
Browse files Browse the repository at this point in the history
Previously, a manual polling of every joystick was performed every 25ms,
resulting in many CPU resources being wasted. This seems to have been
put in place to deal with issues in SDL where joysticks connected after
SDL was initialized did not fire SDL events properly. From manual
testing, this issue seems to have been fixed.

This also fixes a bug in handling of legacy joystick hats, where an
incorrect conversion for the event value was performed.

Finally, this fixes minor typoes and renames
`wxSDLJoyState::ProcessEvent()` to `wxSDLJoyState::ProcessSDLEvent()` to
suppress a warning about a method override.
  • Loading branch information
Steelskin authored and rkitover committed Aug 6, 2022
1 parent 1cfe275 commit 3f2d3c1
Showing 1 changed file with 14 additions and 91 deletions.
105 changes: 14 additions & 91 deletions src/wx/widgets/sdljoy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <wx/timer.h>
#include <SDL.h>

#include "../common/contains.h"
#include "../wxvbam.h"

namespace {
Expand Down Expand Up @@ -39,9 +38,6 @@ static int16_t AxisValueToDirection(int16_t x) {
return 0;
}

// The interval between 2 polls in ms.
const wxLongLong kPollTimeInterval(25);

} // namespace

// For testing a GameController as a Joystick:
Expand Down Expand Up @@ -114,12 +110,9 @@ class wxSDLJoyState : public wxTimer {
bool IsValid() const;

// Processes an SDL event.
void ProcessEvent(int32_t event_type,
uint8_t control_index,
int16_t control_value);

// Polls the current state of the joystick and sends events as needed.
void Poll();
void ProcessSDLEvent(int32_t event_type,
uint8_t control_index,
int16_t control_value);

// Activates or deactivates rumble.
void SetRumble(bool activate_rumble);
Expand Down Expand Up @@ -196,9 +189,9 @@ bool wxSDLJoyState::IsValid() const {
return sdl_joystick_;
}

void wxSDLJoyState::ProcessEvent(int32_t event_type,
uint8_t control_index,
int16_t control_value) {
void wxSDLJoyState::ProcessSDLEvent(int32_t event_type,
uint8_t control_index,
int16_t control_value) {
int16_t previous_value = 0;
wxJoyControl control;
bool value_changed = false;
Expand All @@ -210,7 +203,7 @@ void wxSDLJoyState::ProcessEvent(int32_t event_type,
if (game_controller_) {
return;
}
// Fallhrough.
// Fallthrough.
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
control = wxJoyControl::Button;
Expand Down Expand Up @@ -239,7 +232,7 @@ void wxSDLJoyState::ProcessEvent(int32_t event_type,
if (game_controller_) {
return;
}
// Fallhrough.
// Fallthrough.
case SDL_CONTROLLERAXISMOTION:
control = wxJoyControl::Axis;
previous_value = axis_[control_index];
Expand Down Expand Up @@ -271,58 +264,6 @@ void wxSDLJoyState::ProcessEvent(int32_t event_type,
}
}

void wxSDLJoyState::Poll() {
if (game_controller_) {
for (uint8_t but = 0; but < SDL_CONTROLLER_BUTTON_MAX; but++) {
uint16_t previous_value = buttons_[but];
uint16_t current_value =
SDL_GameControllerGetButton(
game_controller_,
static_cast<SDL_GameControllerButton>(but));

if (previous_value != current_value)
ProcessEvent(SDL_CONTROLLERBUTTONUP, but, current_value);
}

for (uint8_t axis = 0; axis < SDL_CONTROLLER_AXIS_MAX; axis++) {
uint16_t previous_value = axis_[axis];
uint16_t current_value =
AxisValueToDirection(
SDL_GameControllerGetAxis(
game_controller_,
static_cast<SDL_GameControllerAxis>(axis)));

if (previous_value != current_value)
ProcessEvent(SDL_CONTROLLERAXISMOTION, axis, current_value);
}
} else {
for (uint8_t but = 0; but < SDL_JoystickNumButtons(sdl_joystick_); but++) {
uint16_t previous_value = buttons_[but];
uint16_t current_value = SDL_JoystickGetButton(sdl_joystick_, but);

if (previous_value != current_value)
ProcessEvent(SDL_JOYBUTTONUP, but, current_value);
}

for (uint8_t axis = 0; axis < SDL_JoystickNumAxes(sdl_joystick_); axis++) {
uint16_t previous_value = axis_[axis];
uint16_t current_value =
AxisValueToDirection(SDL_JoystickGetButton(sdl_joystick_, axis));

if (previous_value != current_value)
ProcessEvent(SDL_JOYAXISMOTION, axis, current_value);
}

for (uint8_t hat = 0; hat < SDL_JoystickNumHats(sdl_joystick_); hat++) {
uint16_t previous_value = hats_[hat];
uint16_t current_value = SDL_JoystickGetHat(sdl_joystick_, hat);

if (previous_value != current_value)
ProcessEvent(SDL_JOYHATMOTION, hat, current_value);
}
}
}

void wxSDLJoyState::SetRumble(bool activate_rumble) {
rumbling_ = activate_rumble;

Expand Down Expand Up @@ -362,7 +303,6 @@ wxJoyPoller::~wxJoyPoller() {

void wxJoyPoller::Poll() {
SDL_Event e;
bool got_event = false;

while (SDL_PollEvent(&e)) {
switch (e.type) {
Expand All @@ -371,21 +311,19 @@ void wxJoyPoller::Poll() {
{
wxSDLJoyState* joy_state = FindJoyState(e.cbutton.which);
if (joy_state) {
joy_state->ProcessEvent(
joy_state->ProcessSDLEvent(
e.type, e.cbutton.button, e.cbutton.state);
}
got_event = true;
break;
}

case SDL_CONTROLLERAXISMOTION:
{
wxSDLJoyState* joy_state = FindJoyState(e.caxis.which);
if (joy_state) {
joy_state->ProcessEvent(
joy_state->ProcessSDLEvent(
e.type, e.caxis.axis, AxisValueToDirection(e.caxis.value));
}
got_event = true;
break;
}

Expand All @@ -401,47 +339,42 @@ void wxJoyPoller::Poll() {
{
wxSDLJoyState* joy_state = FindJoyState(e.jbutton.which);
if (joy_state) {
joy_state->ProcessEvent(
joy_state->ProcessSDLEvent(
e.type, e.jbutton.button, e.jbutton.state);
}
got_event = true;
break;
}

case SDL_JOYAXISMOTION:
{
wxSDLJoyState* joy_state = FindJoyState(e.jaxis.which);
if (joy_state) {
joy_state->ProcessEvent(
joy_state->ProcessSDLEvent(
e.type, e.jaxis.axis, AxisValueToDirection(e.jaxis.value));
}
got_event = true;
break;
}

case SDL_JOYHATMOTION:
{
wxSDLJoyState* joy_state = FindJoyState(e.jhat.which);
if (joy_state) {
joy_state->ProcessEvent(
e.type, e.jhat.hat, AxisValueToDirection(e.jhat.value));
joy_state->ProcessSDLEvent(
e.type, e.jhat.hat, e.jhat.value);
}
got_event = true;
break;
}

case SDL_JOYDEVICEADDED:
{
// Always remap all controllers.
RemapControllers();
got_event = true;
break;
}

case SDL_JOYDEVICEREMOVED:
{
joystick_states_.erase(e.jdevice.which);
got_event = true;
break;
}

Expand All @@ -450,16 +383,6 @@ void wxJoyPoller::Poll() {
break;
}
}

wxLongLong now = wxGetUTCTimeMillis();
if (got_event) {
last_poll_ = now;
} else if (now - last_poll_ > kPollTimeInterval) {
for (auto&& joy_state : joystick_states_) {
joy_state.second->Poll();
}
last_poll_ = now;
}
}

void wxJoyPoller::RemapControllers() {
Expand Down

0 comments on commit 3f2d3c1

Please sign in to comment.