1
0
Fork 0
mirror of https://github.com/EdgeTX/edgetx.git synced 2025-07-24 16:55:15 +03:00

[Simulator] Fix and refactor Joystick configuration dialog and internal stick-to-radio axis mapping system. Stick was not always showing active in config. dialog, and mappings were sometimes wrong. (#4672)

This commit is contained in:
Max Paperno 2017-03-22 16:02:04 -04:00 committed by Bertrand Songis
parent 4f6931faab
commit 4faf323aed
5 changed files with 111 additions and 464 deletions

View file

@ -21,6 +21,8 @@
#include "joystickdialog.h"
#include "ui_joystickdialog.h"
#include "constants.h"
joystickDialog::joystickDialog(QWidget *parent, int stick) :
QDialog(parent),
ui(new Ui::joystickDialog),
@ -43,6 +45,7 @@ joystickDialog::joystickDialog(QWidget *parent, int stick) :
memcpy(jscal, jscaltmp, sizeof (jscal));
foreach(QComboBox *cb, findChildren<QComboBox *>(QRegExp("jsmapCB_[0-9]+"))) {
populateSourceCombo(cb);
sticks[cb->property("channel").toUInt()] = cb;
}
foreach(QCheckBox *ib, findChildren<QCheckBox *>(QRegExp("ChInv_[0-9]+"))) {
@ -62,7 +65,7 @@ joystickDialog::joystickDialog(QWidget *parent, int stick) :
sliders[i]->setMinimum(jscal[i][0]);
sliders[i]->setMaximum(jscal[i][2]);
invert[i]->setChecked(g.joystick[i].stick_inv());
sticks[i]->setCurrentIndex(g.joystick[i].stick_axe() + 1);
sticks[i]->setCurrentIndex(sticks[i]->findData(g.joystick[i].stick_axe()));
}
ui->backButton->setEnabled(false);
@ -72,7 +75,13 @@ joystickDialog::joystickDialog(QWidget *parent, int stick) :
if (stick < 0)
stick = g.jsCtrl();
loadJoysticks(stick);
if (loadJoysticks(stick)) {
joystickSetEnabled(ui->joystickChkB->isChecked());
joystickOpen(ui->joystickCB->currentIndex());
}
else {
joystickSetEnabled(false);
}
loadStep();
connect(joystick, SIGNAL(axisValueChanged(int, int)), this, SLOT(onjoystickAxisValueChanged(int, int)));
@ -85,7 +94,26 @@ joystickDialog::~joystickDialog()
delete ui;
}
void joystickDialog::loadJoysticks(int stick)
void joystickDialog::populateSourceCombo(QComboBox * cb)
{
int i;
const QString axes[] = {
tr("Left Horizontal"),
tr("Left Vertical"),
tr("Right Vertical"),
tr("Right Horizontal")
};
cb->clear();
cb->addItem(tr("Not Assigned"), -1);
for (i=0; i < 4; ++i) {
cb->addItem(axes[i] % tr(" Stick"), i);
}
for (; i < CPN_MAX_STICKS + CPN_MAX_POTS; ++i) {
cb->addItem(tr("Knob/Slider %1").arg(i - CPN_MAX_STICKS + 1), i);
}
}
bool joystickDialog::loadJoysticks(int stick)
{
QStringList joystickNames;
bool found = false;
@ -101,23 +129,19 @@ void joystickDialog::loadJoysticks(int stick)
joystick->close();
}
ui->joystickCB->insertItems(0, joystickNames);
if (found && stick < joystickNames.size())
if (found && stick < joystickNames.size()) {
ui->joystickCB->setCurrentIndex(stick);
else if (!found)
ui->joystickCB->setCurrentIndex(0);
joystickSetEnabled(found && ui->joystickChkB->isChecked());
}
else if (!found) {
joystickSetEnabled(false);
}
return found;
}
void joystickDialog::joystickOpen(int stick)
{
if (stick == -1 || !ui->joystickChkB->isChecked() || !ui->joystickCB->isEnabled()) {
ui->calibrationWidget->setDisabled(true);
if (stick < 0)
return;
}
ui->calibrationWidget->setEnabled(true);
ui->nextButton->setEnabled(true);
joystick = new Joystick(this, 1, false, 0);
if (joystick && joystick->open(stick)) {
@ -138,8 +162,6 @@ void joystickDialog::joystickSetEnabled(bool enable)
ui->calibrationWidget->setEnabled(enable);
ui->nextButton->setEnabled(enable && step < 4);
ui->backButton->setEnabled(enable && step);
if (enable)
joystickOpen(ui->joystickCB->currentIndex());
}
void joystickDialog::onjoystickAxisValueChanged(int axis, int value)
@ -229,6 +251,9 @@ void joystickDialog::on_okButton_clicked()
g.jsSupport(ui->joystickChkB->isChecked());
g.jsCtrl(ui->joystickCB->currentIndex());
if (joystick)
joystick->close();
if (!g.jsSupport() || g.jsCtrl() < 0) {
this->accept();
return;
@ -241,31 +266,20 @@ void joystickDialog::on_okButton_clicked()
return;
}
int stickAssignments[MAX_JOYSTICKS] = {0};
for (int i = 0; i < MAX_JOYSTICKS; ++i) {
stick = sticks[i]->currentIndex() - 1;
if (stick >= 0 && stick < MAX_JOYSTICKS && ++stickAssignments[stick] > 1) {
QMessageBox::critical(this, tr("Error"), tr("Duplicated stick assignment!"));
return;
stick = sticks[i]->currentData().toInt();
if (stick < 0) {
g.joystick[i].stick_axe(-1);
}
else {
g.joystick[i].stick_axe(stick);
g.joystick[i].stick_max(jscal[i][2]);
g.joystick[i].stick_med(jscal[i][1]);
g.joystick[i].stick_min(jscal[i][0]);
g.joystick[i].stick_inv(invert[i]->isChecked() );
qDebug() << "joystick mapping " << sticks[i]->objectName() << "stick:" << i << "axe:" << stick;
}
}
joystick->close();
for (int i = 0; i < MAX_JOYSTICKS; ++i)
g.joystick[i].remove();
for (int i = 0; i < MAX_JOYSTICKS; ++i) {
stick = sticks[i]->currentIndex() - 1;
qDebug() << "joystick mapping " << sticks[i]->objectName() << "axe:" << i << "stick:" << stick;
if (stick >= 0 && stick < MAX_JOYSTICKS) {
g.joystick[stick].stick_axe( i );
g.joystick[stick].stick_max( jscal[i][2] );
g.joystick[stick].stick_med( jscal[i][1] );
g.joystick[stick].stick_min( jscal[i][0] );
g.joystick[stick].stick_inv( invert[i]->isChecked() );
}
}
this->accept();
}

View file

@ -53,7 +53,8 @@ class joystickDialog : public QDialog
bool started;
private slots:
void loadJoysticks(int stick = -1);
void populateSourceCombo(QComboBox * cb);
bool loadJoysticks(int stick = -1);
void joystickOpen(int stick);
void joystickSetEnabled(bool enable);
void onjoystickAxisValueChanged(int axis, int value);

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>473</width>
<height>335</height>
<width>554</width>
<height>351</height>
</rect>
</property>
<property name="sizePolicy">
@ -90,51 +90,6 @@
<property name="channel" stdset="0">
<number>1</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="0" column="0">
@ -155,51 +110,6 @@
<property name="channel" stdset="0">
<number>2</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="1" column="1">
@ -241,51 +151,6 @@
<property name="channel" stdset="0">
<number>0</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
@ -348,51 +213,6 @@
<property name="channel" stdset="0">
<number>4</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="3" column="1">
@ -434,51 +254,6 @@
<property name="channel" stdset="0">
<number>3</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="5" column="1">
@ -520,51 +295,6 @@
<property name="channel" stdset="0">
<number>5</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
@ -620,51 +350,6 @@
<property name="channel" stdset="0">
<number>6</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="7" column="0">
@ -713,51 +398,6 @@
<property name="channel" stdset="0">
<number>7</number>
</property>
<item>
<property name="text">
<string>Not Assigned</string>
</property>
</item>
<item>
<property name="text">
<string>Right Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Right Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>Left Vertical</string>
</property>
</item>
<item>
<property name="text">
<string>Left Horizontal</string>
</property>
</item>
<item>
<property name="text">
<string>P1</string>
</property>
</item>
<item>
<property name="text">
<string>P2</string>
</property>
</item>
<item>
<property name="text">
<string>P3/LS</string>
</property>
</item>
<item>
<property name="text">
<string>RS</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">

View file

@ -584,25 +584,9 @@ void SimulatorWidget::setupRadioWidgets()
void SimulatorWidget::setupJoysticks()
{
#ifdef JOYSTICKS
static bool joysticksEnabled = false;
if (g.jsSupport() && g.jsCtrl() > -1) {
int count=0, axe;
for (int j=0; j < MAX_JOYSTICKS; j++){
axe = g.joystick[j].stick_axe();
if (axe >= 0 && axe < MAX_JOYSTICKS) {
jsmap[axe] = j + 1;
jscal[axe][0] = g.joystick[j].stick_min();
jscal[axe][1] = g.joystick[j].stick_med();
jscal[axe][2] = g.joystick[j].stick_max();
jscal[axe][3] = g.joystick[j].stick_inv();
count++;
}
}
if (count<3) {
QMessageBox::critical(this, tr("Warning"), tr("Joystick enabled but not configured correctly"));
return;
}
bool joysticksEnabled = false;
if (g.jsSupport() && g.jsCtrl() > -1) {
if (!joystick)
joystick = new Joystick(this);
else
@ -614,24 +598,26 @@ void SimulatorWidget::setupJoysticks()
joystick->sensitivities[j] = 0;
joystick->deadzones[j] = 0;
}
//mode 1,3 -> THR on right
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true);
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_X, true);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_X, true);
connect(joystick, SIGNAL(axisValueChanged(int, int)), this, SLOT(onjoystickAxisValueChanged(int, int)));
connect(joystick, &Joystick::axisValueChanged, this, &SimulatorWidget::onjoystickAxisValueChanged);
joysticksEnabled = true;
}
else {
QMessageBox::critical(this, tr("Warning"), tr("Cannot open joystick, joystick disabled"));
}
}
else if (joysticksEnabled && joystick) {
else if (joystick) {
joystick->close();
disconnect(joystick, 0, this, 0);
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_Y, false);
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_X, false);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_Y, false);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_X, false);
joystick->deleteLater();
joystick = NULL;
}
if (vJoyRight) {
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_X, joysticksEnabled);
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_Y, joysticksEnabled);
}
if (vJoyLeft) {
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_X, joysticksEnabled);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_Y, joysticksEnabled);
}
#endif
}
@ -860,23 +846,31 @@ void SimulatorWidget::centerSticks()
void SimulatorWidget::onjoystickAxisValueChanged(int axis, int value)
{
#ifdef JOYSTICKS
int stick;
if (axis>=0 && axis<=8) {
stick=jsmap[axis];
int stickval;
if (value>jscal[axis][1]) {
if ((jscal[axis][2]-jscal[axis][1])==0)
static const int ttlSticks = CPN_MAX_STICKS;
static const int valueRange = 1024;
if (!joystick || axis >= MAX_JOYSTICKS)
return;
stickval=(1024*(value-jscal[axis][1]))/(jscal[axis][2]-jscal[axis][1]);
}
else {
if ((jscal[axis][1]-jscal[axis][0])==0)
int dlta;
int stick = g.joystick[axis].stick_axe();
if (stick < 0 || stick >= ttlSticks + analogs.count())
return;
stickval=(1024*(value-jscal[axis][1]))/(jscal[axis][1]-jscal[axis][0]);
int stickval = valueRange * (value - g.joystick[axis].stick_med());
if (value > g.joystick[axis].stick_med()) {
if ((dlta = g.joystick[axis].stick_max() - g.joystick[axis].stick_med()))
stickval /= dlta;
}
if (jscal[axis][3]==1) {
else if ((dlta = g.joystick[axis].stick_med() - g.joystick[axis].stick_min())) {
stickval /= dlta;
}
if (g.joystick[axis].stick_inv())
stickval *= -1;
}
if (stick==1 ) {
vJoyRight->setStickY(-stickval/1024.0);
}
@ -889,9 +883,9 @@ void SimulatorWidget::onjoystickAxisValueChanged(int axis, int value)
else if (stick==4) {
vJoyLeft->setStickX(stickval/1024.0);
}
else if (stick >= 5 && stick < 5 + analogs.count()) {
analogs[stick-5]->setValue(stickval);
}
else if (stick > ttlSticks) {
analogs[stick-ttlSticks-1]->setValue(stickval);
}
#endif
}

View file

@ -137,8 +137,6 @@ class SimulatorWidget : public QWidget
#ifdef JOYSTICKS
Joystick *joystick;
int jscal[8][4];
int jsmap[8];
#endif
private slots: