Browse Source

Rollback joystick changes

pull/1278/head
Yuri Pourre 5 years ago committed by Anders Jenbo
parent
commit
df56d6a03b
  1. 2
      Source/gmenu.cpp
  2. 99
      SourceX/controls/controller.cpp
  3. 24
      SourceX/controls/controller.h
  4. 119
      SourceX/controls/controller_motion.cpp
  5. 13
      SourceX/controls/controller_motion.h
  6. 16
      SourceX/controls/devices/game_controller.cpp
  7. 3
      SourceX/controls/devices/game_controller.h
  8. 16
      SourceX/controls/devices/joystick.cpp
  9. 4
      SourceX/controls/devices/joystick.h
  10. 22
      SourceX/controls/devices/kbcontroller.cpp
  11. 16
      SourceX/controls/devices/kbcontroller.h
  12. 2
      SourceX/controls/game_controls.cpp
  13. 2
      SourceX/controls/menu_controls.cpp
  14. 10
      SourceX/controls/plrctrls.cpp
  15. 4
      SourceX/display.cpp

2
Source/gmenu.cpp

@ -235,7 +235,7 @@ static void gmenu_draw_menu_item(CelOutputBuffer out, TMenuItem *pItem, int y)
static void GameMenuMove()
{
static AxisDirectionRepeater repeater;
const AxisDirection move_dir = repeater.Get(controller.GetLeftStickOrDpadDirection());
const AxisDirection move_dir = repeater.Get(GetLeftStickOrDpadDirection());
if (move_dir.x != AxisDirectionX_NONE)
gmenu_left_right(move_dir.x == AxisDirectionX_RIGHT);
if (move_dir.y != AxisDirectionY_NONE)

99
SourceX/controls/controller.cpp

@ -8,94 +8,6 @@
namespace dvl {
AxisDirection Controller::GetLeftStickOrDpadDirection(bool allow_dpad)
{
const float stickX = leftStickX;
const float stickY = leftStickY;
AxisDirection result { AxisDirectionX_NONE, AxisDirectionY_NONE };
if (stickY >= 0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_UP))) {
result.y = AxisDirectionY_UP;
} else if (stickY <= -0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_DOWN))) {
result.y = AxisDirectionY_DOWN;
}
if (stickX <= -0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_LEFT))) {
result.x = AxisDirectionX_LEFT;
} else if (stickX >= 0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_RIGHT))) {
result.x = AxisDirectionX_RIGHT;
}
return result;
}
void Controller::ScaleJoysticks()
{
const float rightDeadzone = 0.07;
const float leftDeadzone = 0.07;
if (leftStickNeedsScaling) {
leftStickX = leftStickXUnscaled;
leftStickY = leftStickYUnscaled;
ScaleJoystickAxes(&leftStickX, &leftStickY, leftDeadzone);
leftStickNeedsScaling = false;
}
if (rightStickNeedsScaling) {
rightStickX = rightStickXUnscaled;
rightStickY = rightStickYUnscaled;
ScaleJoystickAxes(&rightStickX, &rightStickY, rightDeadzone);
rightStickNeedsScaling = false;
}
}
void Controller::ScaleJoystickAxes(float *x, float *y, float deadzone)
{
//radial and scaled dead_zone
//http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html
//input values go from -32767.0...+32767.0, output values are from -1.0 to 1.0;
if (deadzone == 0) {
return;
}
if (deadzone >= 1.0) {
*x = 0;
*y = 0;
return;
}
const float maximum = 32767.0f;
float analog_x = *x;
float analog_y = *y;
float dead_zone = deadzone * maximum;
float magnitude = std::sqrt(analog_x * analog_x + analog_y * analog_y);
if (magnitude >= dead_zone) {
// find scaled axis values with magnitudes between zero and maximum
float scalingFactor = 1.0 / magnitude * (magnitude - dead_zone) / (maximum - dead_zone);
analog_x = (analog_x * scalingFactor);
analog_y = (analog_y * scalingFactor);
// clamp to ensure results will never exceed the max_axis value
float clamping_factor = 1.0f;
float abs_analog_x = std::fabs(analog_x);
float abs_analog_y = std::fabs(analog_y);
if (abs_analog_x > 1.0 || abs_analog_y > 1.0) {
if (abs_analog_x > abs_analog_y) {
clamping_factor = 1 / abs_analog_x;
} else {
clamping_factor = 1 / abs_analog_y;
}
}
*x = (clamping_factor * analog_x);
*y = (clamping_factor * analog_y);
} else {
*x = 0;
*y = 0;
}
}
ControllerButtonEvent ToControllerButtonEvent(const SDL_Event &event)
{
ControllerButtonEvent result { ControllerButton_NONE, false };
@ -111,15 +23,6 @@ ControllerButtonEvent ToControllerButtonEvent(const SDL_Event &event)
break;
}
#if HAS_KBCTRL == 1
KeyboardController *const keyboardController = KeyboardController::Get(event);
if (keyboardController != NULL) {
result.button = keyboardController->ToControllerButton(event);
if (result.button != ControllerButton_NONE)
return result;
}
#endif
#ifndef USE_SDL1
GameController *const controller = GameController::Get(event);
if (controller != NULL) {
@ -129,7 +32,7 @@ ControllerButtonEvent ToControllerButtonEvent(const SDL_Event &event)
}
#endif
const Joystick *const joystick = Joystick::Get(event);
const Joystick *joystick = Joystick::Get(event);
if (joystick != NULL)
result.button = joystick->ToControllerButton(event);

24
SourceX/controls/controller.h

@ -3,7 +3,6 @@
#include <SDL.h>
#include "all.h"
#include "./axis_direction.h"
#include "./controller_buttons.h"
namespace dvl {
@ -13,29 +12,6 @@ struct ControllerButtonEvent {
bool up;
};
class Controller {
public:
// Raw axis values.
float leftStickX, leftStickY, rightStickX, rightStickY;
// Axis values scaled to [-1, 1] range and clamped to a deadzone.
float leftStickXUnscaled, leftStickYUnscaled, rightStickXUnscaled, rightStickYUnscaled;
// Whether stick positions have been updated and need rescaling.
bool leftStickNeedsScaling, rightStickNeedsScaling;
// Returns direction of the left thumb stick or DPad (if allow_dpad = true).
AxisDirection GetLeftStickOrDpadDirection(bool allow_dpad = true);
// Normalize joystick values
void ScaleJoysticks();
// NOTE: Not idempotent because of how it handles axis triggers.
// Must be called exactly once for each SDL input event.
ControllerButton ToControllerButton(const SDL_Event &event) const;
private:
void ScaleJoystickAxes(float *x, float *y, float deadzone);
};
// NOTE: Not idempotent because of how it handles axis triggers.
// Must be called exactly once per SDL input event.
ControllerButtonEvent ToControllerButtonEvent(const SDL_Event &event);

119
SourceX/controls/controller_motion.cpp

@ -10,10 +10,54 @@
namespace dvl {
Controller controller;
namespace {
void ScaleJoystickAxes(float *x, float *y, float deadzone)
{
//radial and scaled dead_zone
//http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html
//input values go from -32767.0...+32767.0, output values are from -1.0 to 1.0;
if (deadzone == 0) {
return;
}
if (deadzone >= 1.0) {
*x = 0;
*y = 0;
return;
}
const float maximum = 32767.0f;
float analog_x = *x;
float analog_y = *y;
float dead_zone = deadzone * maximum;
float magnitude = std::sqrt(analog_x * analog_x + analog_y * analog_y);
if (magnitude >= dead_zone) {
// find scaled axis values with magnitudes between zero and maximum
float scalingFactor = 1.0 / magnitude * (magnitude - dead_zone) / (maximum - dead_zone);
analog_x = (analog_x * scalingFactor);
analog_y = (analog_y * scalingFactor);
// clamp to ensure results will never exceed the max_axis value
float clamping_factor = 1.0f;
float abs_analog_x = std::fabs(analog_x);
float abs_analog_y = std::fabs(analog_y);
if (abs_analog_x > 1.0 || abs_analog_y > 1.0) {
if (abs_analog_x > abs_analog_y) {
clamping_factor = 1 / abs_analog_x;
} else {
clamping_factor = 1 / abs_analog_y;
}
}
*x = (clamping_factor * analog_x);
*y = (clamping_factor * analog_y);
} else {
*x = 0;
*y = 0;
}
}
// SELECT + D-Pad to simulate right stick movement.
bool SimulateRightStickWithDpad(const SDL_Event &event, ControllerButtonEvent ctrl_event)
{
@ -22,7 +66,7 @@ bool SimulateRightStickWithDpad(const SDL_Event &event, ControllerButtonEvent ct
static bool simulating = false;
if (ctrl_event.button == ControllerButton_BUTTON_BACK) {
if (ctrl_event.up && simulating) {
controller.rightStickX = controller.rightStickY = 0;
rightStickX = rightStickY = 0;
simulating = false;
}
return false;
@ -31,50 +75,97 @@ bool SimulateRightStickWithDpad(const SDL_Event &event, ControllerButtonEvent ct
return false;
switch (ctrl_event.button) {
case ControllerButton_BUTTON_DPAD_LEFT:
controller.rightStickX = ctrl_event.up ? 0 : -1;
rightStickX = ctrl_event.up ? 0 : -1;
break;
case ControllerButton_BUTTON_DPAD_RIGHT:
controller.rightStickX = ctrl_event.up ? 0 : 1;
rightStickX = ctrl_event.up ? 0 : 1;
break;
case ControllerButton_BUTTON_DPAD_UP:
controller.rightStickY = ctrl_event.up ? 0 : 1;
rightStickY = ctrl_event.up ? 0 : 1;
break;
case ControllerButton_BUTTON_DPAD_DOWN:
controller.rightStickY = ctrl_event.up ? 0 : -1;
rightStickY = ctrl_event.up ? 0 : -1;
break;
default:
return false;
}
simulating = !(controller.rightStickX == 0 && controller.rightStickY == 0);
simulating = !(rightStickX == 0 && rightStickY == 0);
return true;
}
} // namespace
float leftStickX, leftStickY, rightStickX, rightStickY;
float leftStickXUnscaled, leftStickYUnscaled, rightStickXUnscaled, rightStickYUnscaled;
bool leftStickNeedsScaling, rightStickNeedsScaling;
namespace {
void ScaleJoysticks()
{
const float rightDeadzone = 0.07;
const float leftDeadzone = 0.07;
if (leftStickNeedsScaling) {
leftStickX = leftStickXUnscaled;
leftStickY = leftStickYUnscaled;
ScaleJoystickAxes(&leftStickX, &leftStickY, leftDeadzone);
leftStickNeedsScaling = false;
}
if (rightStickNeedsScaling) {
rightStickX = rightStickXUnscaled;
rightStickY = rightStickYUnscaled;
ScaleJoystickAxes(&rightStickX, &rightStickY, rightDeadzone);
rightStickNeedsScaling = false;
}
}
} // namespace
// Updates motion state for mouse and joystick sticks.
bool ProcessControllerMotion(const SDL_Event &event, ControllerButtonEvent ctrl_event)
{
#ifndef USE_SDL1
GameController *const controller = GameController::Get(event);
if (controller != NULL && controller->ProcessAxisMotion(event)) {
controller->ScaleJoysticks();
ScaleJoysticks();
return true;
}
#endif
Joystick *const joystick = Joystick::Get(event);
if (joystick != NULL && joystick->ProcessAxisMotion(event)) {
joystick->ScaleJoysticks();
ScaleJoysticks();
return true;
}
#if HAS_KBCTRL == 1
KeyboardController *const keyboardController = KeyboardController::Get(event);
if (keyboardController != NULL && keyboardController->ProcessAxisMotion(event)) {
keyboardController->ScaleJoysticks();
if (ProcessKbCtrlAxisMotion(event))
return true;
}
#endif
return SimulateRightStickWithDpad(event, ctrl_event);
}
AxisDirection GetLeftStickOrDpadDirection(bool allow_dpad)
{
const float stickX = leftStickX;
const float stickY = leftStickY;
AxisDirection result { AxisDirectionX_NONE, AxisDirectionY_NONE };
if (stickY >= 0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_UP))) {
result.y = AxisDirectionY_UP;
} else if (stickY <= -0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_DOWN))) {
result.y = AxisDirectionY_DOWN;
}
if (stickX <= -0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_LEFT))) {
result.x = AxisDirectionX_LEFT;
} else if (stickX >= 0.5 || (allow_dpad && IsControllerButtonPressed(ControllerButton_BUTTON_DPAD_RIGHT))) {
result.x = AxisDirectionX_RIGHT;
}
return result;
}
} // namespace dvl

13
SourceX/controls/controller_motion.h

@ -4,13 +4,24 @@
#include <SDL.h>
#include "./axis_direction.h"
#include "./controller.h"
namespace dvl {
extern struct Controller controller;
// Raw axis values.
extern float leftStickXUnscaled, leftStickYUnscaled, rightStickXUnscaled, rightStickYUnscaled;
// Axis values scaled to [-1, 1] range and clamped to a deadzone.
extern float leftStickX, leftStickY, rightStickX, rightStickY;
// Whether stick positions have been updated and need rescaling.
extern bool leftStickNeedsScaling, rightStickNeedsScaling;
// Updates motion state for mouse and joystick sticks.
bool ProcessControllerMotion(const SDL_Event &event, ControllerButtonEvent ctrl_event);
// Returns direction of the left thumb stick or DPad (if allow_dpad = true).
AxisDirection GetLeftStickOrDpadDirection(bool allow_dpad = true);
} // namespace dvl

16
SourceX/controls/devices/game_controller.cpp

@ -130,20 +130,20 @@ bool GameController::ProcessAxisMotion(const SDL_Event &event)
return false;
switch (event.caxis.axis) {
case SDL_CONTROLLER_AXIS_LEFTX:
controller.leftStickXUnscaled = event.caxis.value;
controller.leftStickNeedsScaling = true;
leftStickXUnscaled = event.caxis.value;
leftStickNeedsScaling = true;
break;
case SDL_CONTROLLER_AXIS_LEFTY:
controller.leftStickYUnscaled = -event.caxis.value;
controller.leftStickNeedsScaling = true;
leftStickYUnscaled = -event.caxis.value;
leftStickNeedsScaling = true;
break;
case SDL_CONTROLLER_AXIS_RIGHTX:
controller.rightStickXUnscaled = event.caxis.value;
controller.rightStickNeedsScaling = true;
rightStickXUnscaled = event.caxis.value;
rightStickNeedsScaling = true;
break;
case SDL_CONTROLLER_AXIS_RIGHTY:
controller.rightStickYUnscaled = -event.caxis.value;
controller.rightStickNeedsScaling = true;
rightStickYUnscaled = -event.caxis.value;
rightStickNeedsScaling = true;
break;
default:
return false;

3
SourceX/controls/devices/game_controller.h

@ -5,13 +5,12 @@
#include <SDL.h>
#include "controls/controller.h"
#include "controls/controller_buttons.h"
#ifndef USE_SDL1
namespace dvl {
class GameController : public Controller {
class GameController {
static std::vector<GameController> *const controllers_;
public:

16
SourceX/controls/devices/joystick.cpp

@ -219,26 +219,26 @@ bool Joystick::ProcessAxisMotion(const SDL_Event &event)
switch (event.jaxis.axis) {
#ifdef JOY_AXIS_LEFTX
case JOY_AXIS_LEFTX:
controller.leftStickXUnscaled = event.jaxis.value;
controller.leftStickNeedsScaling = true;
leftStickXUnscaled = event.jaxis.value;
leftStickNeedsScaling = true;
break;
#endif
#ifdef JOY_AXIS_LEFTY
case JOY_AXIS_LEFTY:
controller.leftStickYUnscaled = -event.jaxis.value;
controller.leftStickNeedsScaling = true;
leftStickYUnscaled = -event.jaxis.value;
leftStickNeedsScaling = true;
break;
#endif
#ifdef JOY_AXIS_RIGHTX
case JOY_AXIS_RIGHTX:
controller.rightStickXUnscaled = event.jaxis.value;
controller.rightStickNeedsScaling = true;
rightStickXUnscaled = event.jaxis.value;
rightStickNeedsScaling = true;
break;
#endif
#ifdef JOY_AXIS_RIGHTY
case JOY_AXIS_RIGHTY:
controller.rightStickYUnscaled = -event.jaxis.value;
controller.rightStickNeedsScaling = true;
rightStickYUnscaled = -event.jaxis.value;
rightStickNeedsScaling = true;
break;
#endif
default:

4
SourceX/controls/devices/joystick.h

@ -14,7 +14,7 @@
namespace dvl {
class Joystick : public Controller {
class Joystick {
static std::vector<Joystick> *const joysticks_;
public:
@ -25,8 +25,6 @@ public:
static const std::vector<Joystick> &All();
static bool IsPressedOnAnyJoystick(ControllerButton button);
// NOTE: Not idempotent.
// Must be called exactly once for each SDL input event.
ControllerButton ToControllerButton(const SDL_Event &event) const;
bool IsPressed(ControllerButton button) const;
bool ProcessAxisMotion(const SDL_Event &event);

22
SourceX/controls/devices/kbcontroller.cpp

@ -8,21 +8,7 @@
namespace dvl {
std::vector<KeyboardController> *const KeyboardController::keyboardControllers_ = new std::vector<KeyboardController>;
KeyboardController *KeyboardController::Get(const SDL_Event &event) {
// Return the first (and only) one
KeyboardController &keyboardController = (*keyboardControllers_)[0];
return &keyboardController;
}
bool KeyboardController::ProcessAxisMotion(const SDL_Event &event)
{
// Mapping keyboard to right stick axis not implemented.
return false;
}
ControllerButton KeyboardController::ToControllerButton(const SDL_Event &event) const
ControllerButton KbCtrlToControllerButton(const SDL_Event &event)
{
switch (event.type) {
case SDL_KEYDOWN:
@ -178,5 +164,11 @@ bool IsKbCtrlButtonPressed(ControllerButton button)
#endif
}
bool ProcessKbCtrlAxisMotion(const SDL_Event &event)
{
// Mapping keyboard to right stick axis not implemented.
return false;
}
} // namespace dvl
#endif

16
SourceX/controls/devices/kbcontroller.h

@ -7,25 +7,15 @@
#if HAS_KBCTRL == 1
#include <SDL.h>
#include "controls/controller.h"
#include "controls/controller_buttons.h"
namespace dvl {
class KeyboardController : public Controller {
static std::vector<KeyboardController> *const keyboardControllers_;
public:
static void Add(int device_index);
static KeyboardController *Get(const SDL_Event &event);
ControllerButton ToControllerButton(const SDL_Event &event) const;
//bool ProcessKbCtrlAxisMotion(const SDL_Event &event);
bool ProcessAxisMotion(const SDL_Event &event);
};
ControllerButton KbCtrlToControllerButton(const SDL_Event &event);
bool IsKbCtrlButtonPressed(ControllerButton button);
bool ProcessKbCtrlAxisMotion(const SDL_Event &event);
} // namespace dvl
#endif

2
SourceX/controls/game_controls.cpp

@ -347,7 +347,7 @@ bool GetGameAction(const SDL_Event &event, ControllerButtonEvent ctrl_event, Gam
AxisDirection GetMoveDirection()
{
return controller.GetLeftStickOrDpadDirection(/*allow_dpad=*/!sgOptions.Controller.bDpadHotkeys);
return GetLeftStickOrDpadDirection(/*allow_dpad=*/!sgOptions.Controller.bDpadHotkeys);
}
} // namespace dvl

2
SourceX/controls/menu_controls.cpp

@ -11,7 +11,7 @@ namespace dvl {
MenuAction GetMenuHeldUpDownAction()
{
static AxisDirectionRepeater repeater;
const AxisDirection dir = repeater.Get(controller.GetLeftStickOrDpadDirection());
const AxisDirection dir = repeater.Get(GetLeftStickOrDpadDirection());
switch (dir.y) {
case AxisDirectionY_UP:
return MenuAction_UP;

10
SourceX/controls/plrctrls.cpp

@ -865,7 +865,7 @@ HandleLeftStickOrDPadFn GetLeftStickOrDPadGameUIHandler()
void ProcessLeftStickOrDPadGameUI() {
HandleLeftStickOrDPadFn handler = GetLeftStickOrDPadGameUIHandler();
if (handler != NULL)
handler(controller.GetLeftStickOrDpadDirection(true));
handler(GetLeftStickOrDpadDirection(true));
}
void Movement()
@ -898,8 +898,8 @@ struct RightStickAccumulator {
{
const Uint32 tc = SDL_GetTicks();
const int dtc = tc - lastTc;
hiresDX += controller.rightStickX * dtc;
hiresDY += controller.rightStickY * dtc;
hiresDX += rightStickX * dtc;
hiresDY += rightStickY * dtc;
const int dx = hiresDX / slowdown;
const int dy = hiresDY / slowdown;
*x += dx;
@ -977,14 +977,14 @@ bool IsAutomapActive()
bool IsMovingMouseCursorWithController()
{
return controller.rightStickX != 0 || controller.rightStickY != 0;
return rightStickX != 0 || rightStickY != 0;
}
void HandleRightStickMotion()
{
static RightStickAccumulator acc;
// deadzone is handled in ScaleJoystickAxes() already
if (controller.rightStickX == 0 && controller.rightStickY == 0) {
if (rightStickX == 0 && rightStickY == 0) {
acc.clear();
return;
}

4
SourceX/display.cpp

@ -4,6 +4,7 @@
#include "controls/controller.h"
#include "controls/devices/game_controller.h"
#include "controls/devices/joystick.h"
#include "controls/devices/kbcontroller.h"
#ifdef __vita__
#include <psp2/power.h>
@ -148,9 +149,6 @@ bool SpawnWindow(const char *lpWindowName)
// TODO: There is a bug in SDL2 on Switch where it does not report controllers on startup (Jan 1, 2020)
GameController::Add(0);
#endif
#endif
#if HAS_KBCTRL == 1
KeyboardController::Add(0);
#endif
int width = sgOptions.Graphics.nWidth;

Loading…
Cancel
Save