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

View file

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

View file

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>473</width> <width>554</width>
<height>335</height> <height>351</height>
</rect> </rect>
</property> </property>
<property name="sizePolicy"> <property name="sizePolicy">
@ -90,51 +90,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>1</number> <number>1</number>
</property> </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> </widget>
</item> </item>
<item row="0" column="0"> <item row="0" column="0">
@ -155,51 +110,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>2</number> <number>2</number>
</property> </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> </widget>
</item> </item>
<item row="1" column="1"> <item row="1" column="1">
@ -241,51 +151,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>0</number> <number>0</number>
</property> </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> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">
@ -348,51 +213,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>4</number> <number>4</number>
</property> </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> </widget>
</item> </item>
<item row="3" column="1"> <item row="3" column="1">
@ -434,51 +254,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>3</number> <number>3</number>
</property> </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> </widget>
</item> </item>
<item row="5" column="1"> <item row="5" column="1">
@ -520,51 +295,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>5</number> <number>5</number>
</property> </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> </widget>
</item> </item>
<item row="4" column="0"> <item row="4" column="0">
@ -620,51 +350,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>6</number> <number>6</number>
</property> </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> </widget>
</item> </item>
<item row="7" column="0"> <item row="7" column="0">
@ -713,51 +398,6 @@
<property name="channel" stdset="0"> <property name="channel" stdset="0">
<number>7</number> <number>7</number>
</property> </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> </widget>
</item> </item>
<item row="0" column="1"> <item row="0" column="1">

View file

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

View file

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