Files
edgetx-gx12/companion/src/simulation/joystick.cpp
T
e1fe7fce89 feat(radio,cpn): Updates for new joystick system (#3400)
* Reduce RAM usage for advanced joystick system on radio:
- Don't allocate memory blocks unless joystick mode is being used.
Support multiple radio joystick configurations in Companion:
- Save configured joystick settings by joystick name in Companion settings.
- Save last joystick name used in each profile.
- Reload joystick settings by name when profile is changed.

* Only show configuration for used axes and buttons in Companion.
Send actual number of configured joystick buttons from radio in USB packet.

* Fix issue where USB joystick not recognised if no buttons configured.

* Fix compiler warnings.

* Remove debugging.

* Fix crash in Companion.

* Change channel 8 to type 'dial', workaround for Linux mapping issue.

---------

Co-authored-by: Phil Mitchell <phil.a.mitchell@gmail.com>
2023-04-21 14:27:41 +10:00

180 lines
4.4 KiB
C++

/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "joystick.h"
Joystick::Joystick(QObject *parent, int joystickEventTimeout, bool doAutoRepeat, int repeatDelay)
: QObject(parent)
{
if ( SDL_WasInit(SDL_INIT_JOYSTICK) ) {
int i;
for (i = 0; i < SDL_NumJoysticks(); i++)
{
SDL_Joystick* joy = SDL_JoystickOpen(i);
if(joy == nullptr)
continue;
joystickNames.append(SDL_JoystickName(joy));
SDL_JoystickClose(joy);
}
connect(&joystickTimer, SIGNAL(timeout()), this, SLOT(processEvents()));
} else {
fprintf(stderr, "ERROR: couldn't initialize SDL joystick support\n");
}
joystick = NULL;
numAxes = numButtons = numHats = numTrackballs = 0;
autoRepeat = doAutoRepeat;
autoRepeatDelay = repeatDelay;
eventTimeout = joystickEventTimeout;
}
Joystick::~Joystick()
{
if ( isOpen() )
close();
}
bool Joystick::open(int stick)
{
if (isOpen())
close();
joystick = SDL_JoystickOpen(stick);
if (joystick) {
numAxes = SDL_JoystickNumAxes(joystick);
numButtons = SDL_JoystickNumButtons(joystick);
numHats = SDL_JoystickNumHats(joystick);
numTrackballs = SDL_JoystickNumBalls(joystick);
joystickTimer.start(eventTimeout);
for (int i = 0; i < numButtons; i += 1) {
buttons[i] = -1;
}
return true;
}
else {
fprintf(stderr, "ERROR: couldn't open SDL joystick #%d", stick);
return false;
}
}
void Joystick::close()
{
joystickTimer.stop();
if (joystick) {
SDL_JoystickClose(joystick);
joystick = NULL;
}
numAxes = numButtons = numHats = numTrackballs = 0;
}
void Joystick::processEvents()
{
if ( !isOpen() )
return;
SDL_JoystickUpdate();
int i;
for (i = 0; i < numAxes; i++) {
Sint16 moved = SDL_JoystickGetAxis(joystick, i);
if ( abs(moved) >= deadzones[i] ) {
if ( (moved != axes[i]) ) {
int deltaMoved = abs(axes[i] - moved);
if ( deltaMoved >= sensitivities[i] )
emit axisValueChanged(i, moved);
axes[i] = moved;
axisRepeatTimers[i].restart();
}
else if (autoRepeat && moved != 0) {
if ( axisRepeatTimers[i].elapsed() >= autoRepeatDelay ) {
emit axisValueChanged(i, moved);
axes[i] = moved;
}
}
else {
axisRepeatTimers[i].restart();
}
}
// else {
// emit axisValueChanged(i, 0);
// }
}
for (i = 0; i < numButtons; i++) {
Uint8 changed = SDL_JoystickGetButton(joystick, i);
if (changed != buttons[i]) {
emit buttonValueChanged(i, (bool) changed);
buttons[i] = changed;
buttonRepeatTimers[i].restart();
}
else if (autoRepeat && changed != 0) {
if (buttonRepeatTimers[i].elapsed() >= autoRepeatDelay) {
emit buttonValueChanged(i, (bool) changed);
buttons[i] = changed;
}
}
else {
buttonRepeatTimers[i].restart();
}
}
for (i = 0; i < numHats; i++) {
Uint8 changed = SDL_JoystickGetHat(joystick, i);
if (changed != hats[i]) {
emit hatValueChanged(i, changed);
hats[i] = changed;
hatRepeatTimers[i].restart();
}
else if (autoRepeat && changed != 0) {
if (hatRepeatTimers[i].elapsed() >= autoRepeatDelay) {
emit hatValueChanged(i, changed);
hats[i] = changed;
}
}
else {
hatRepeatTimers[i].restart();
}
}
for (i = 0; i < numTrackballs; i++) {
int dx, dy;
SDL_JoystickGetBall(joystick, i, &dx, &dy);
if (dx != 0 || dy != 0)
emit trackballValueChanged(i, dx, dy);
}
}
int Joystick::getAxisValue(int axis)
{
if ( isOpen() ) {
SDL_JoystickUpdate();
return SDL_JoystickGetAxis(joystick, axis);
} else
return 0;
}
int Joystick::findCurrent(QString jsName)
{
for (int i = 0; i < joystickNames.size(); i += 1) {
if (joystickNames[i] == jsName) {
return i;
}
}
return 0;
}