Skip to content

Commit

Permalink
PFBA: fix joystick controls with radial deadzone & symmetric directions
Browse files Browse the repository at this point in the history
  • Loading branch information
rsn8887 committed Aug 4, 2017
1 parent c7b0c5a commit 8a8e3d7
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 35 deletions.
115 changes: 81 additions & 34 deletions pfba/deps/libcross2d/src/sdl2/sdl2_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "sdl2_input.h"

#include "math.h" // need square root for radial deadzone

static int key_id[KEY_COUNT]{
Input::Key::KEY_UP,
Input::Key::KEY_DOWN,
Expand Down Expand Up @@ -123,40 +125,85 @@ void SDL2Input::process_axis(Input::Player &player, int rotate) {
if (!player.enabled || !player.data) {
return;
}

short lx = (short) SDL_JoystickGetAxis((SDL_Joystick *) player.data, player.lx.id);
short rx = (short) SDL_JoystickGetAxis((SDL_Joystick *) player.data, player.rx.id);
if (lx > player.dead_zone || rx > player.dead_zone) {
player.lx.value = lx;
player.rx.value = rx;
player.state |= (rotate == 1) ? Input::Key::KEY_DOWN : (rotate == 3) ? Input::Key::KEY_UP
: Input::Key::KEY_RIGHT;
} else if (lx < -player.dead_zone || rx < -player.dead_zone) {
player.lx.value = lx;
player.rx.value = rx;
player.state |= (rotate == 1) ? Input::Key::KEY_UP : (rotate == 3) ? Input::Key::KEY_DOWN
: Input::Key::KEY_LEFT;
} else {
player.lx.value = 0;
player.rx.value = 0;
}

short ly = (short) SDL_JoystickGetAxis((SDL_Joystick *) player.data, player.ly.id);
short ry = (short) SDL_JoystickGetAxis((SDL_Joystick *) player.data, player.ry.id);
if (ly > player.dead_zone || ry > player.dead_zone) {
player.ly.value = ly;
player.ry.value = ry;
player.state |= (rotate == 1) ? Input::Key::KEY_LEFT : (rotate == 3) ? Input::Key::KEY_RIGHT
: Input::Key::KEY_DOWN;
} else if (ly < -player.dead_zone || ry < -player.dead_zone) {
player.ly.value = ly;
player.ry.value = ry;
player.state |= (rotate == 1) ? Input::Key::KEY_RIGHT : (rotate == 3) ? Input::Key::KEY_LEFT
: Input::Key::KEY_UP;
} else {
player.ly.value = 0;
player.ry.value = 0;
}

float analogX = 0.0f;
float analogY = 0.0f;
float deadZone = (float) player.dead_zone;
float scalingFactor = 1.0f;
float magnitude = 0.0f;
bool up = false, down = false, left = false, right = false;
Axis *currentStickXAxis = NULL;
Axis *currentStickYAxis = NULL;

for (int i = 0; i<=1; i++) {

if (i == 0) {
// left stick
currentStickXAxis = &(player.lx);
currentStickYAxis = &(player.ly);
} else {
// right stick
currentStickXAxis = &(player.rx);
currentStickYAxis = &(player.ry);
}
analogX = (float) (SDL_JoystickGetAxis((SDL_Joystick *) player.data, currentStickXAxis->id));
analogY = (float) (SDL_JoystickGetAxis((SDL_Joystick *) player.data, currentStickYAxis->id));

//radial and scaled deadzone
//http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html

if (magnitude=sqrt(analogX * analogX + analogY * analogY) >= deadZone) {

// analog control
scalingFactor=1.0f/magnitude * (magnitude-deadZone)/(32769.0f-deadZone);
currentStickXAxis->value = (short) (analogX * scalingFactor);
currentStickYAxis->value = (short) (analogY * scalingFactor);

// symmetric angular zones for all eight digital directions
analogY = -analogY;
if (analogY > 0 && analogX > 0) {
// upper right quadrant
if (2*analogY > analogX)
up = true;
if (2*analogX > analogY)
right = true;
} else if (analogY > 0 && analogX <= 0) {
// upper left quadrant
if (2*analogY > (-analogX))
up = true;
if (2*(-analogX) > analogY)
left = true;
} else if (analogY <= 0 && analogX > 0) {
// lower right quadrant
if (2*(-analogY) > analogX)
down = true;
if (2*analogX > (-analogY))
right = true;
} else if (analogY <= 0 && analogX <= 0) {
// lower left quadrant
if (2*(-analogY) > (-analogX))
down = true;
if (2*(-analogX) > (-analogY))
left = true;
}

if (right)
player.state |= (rotate == 1) ? Input::Key::KEY_DOWN :
(rotate == 3) ? Input::Key::KEY_UP : Input::Key::KEY_RIGHT;
if (left)
player.state |= (rotate == 1) ? Input::Key::KEY_UP :
(rotate == 3) ? Input::Key::KEY_DOWN : Input::Key::KEY_LEFT;
if (up)
player.state |= (rotate == 1) ? Input::Key::KEY_RIGHT :
(rotate == 3) ? Input::Key::KEY_LEFT : Input::Key::KEY_UP;
if (down)
player.state |= (rotate == 1) ? Input::Key::KEY_LEFT :
(rotate == 3) ? Input::Key::KEY_RIGHT : Input::Key::KEY_DOWN;
} else {
currentStickXAxis->value = 0;
currentStickYAxis->value = 0;
} // end if (magnitude >= deadZone)
} // end for
}

void SDL2Input::process_hat(Input::Player &player, int rotate) {
Expand Down
3 changes: 2 additions & 1 deletion pfba/gui/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ void Gui::Run() {
} else if (key & Input::Key::KEY_FIRE1) {
if (romSelected != NULL
&& romSelected->state != RomList::RomState::MISSING) {
for (int i = 0; i < 3; i++) {
for (int i = 0; i < 6; i++) {
Clear();
Flip();
}
Expand Down Expand Up @@ -1012,6 +1012,7 @@ int Gui::MessageBox(const char *message, const char *choice1, const char *choice
}

input->Clear(0);

}

int Gui::GetButton() {
Expand Down

0 comments on commit 8a8e3d7

Please sign in to comment.