feat: New advanced joystick mode on radio, improvements to Companion and Simulator joystick support (#3111)

* Allow switches on the connected radio to control switches in the simulator via the joystick interface.

* Merge configurable radio joystick interface from banyaszg.

* Add two more 'axis' channels to companion.

* Fix 6POS from USB joystick to simulator.

* Reduce data size.

* Fix build error on B&W radios.

* Add 'Companion' button mode to work with the button logic in the Companion app.

* Build Companion joystick setup layout at runtime.
Change #define names for simulator joystick.
Allow 15 axes and 32 buttons.
Initial support for trim sliders.

* Remove custom joystick button type for companion - use 3 buttons per switch in companion to control simulator switch state.

* Fix joystick constructor calls parameters. Connect some radio joystick trims to simulator widgets.

* Restore 'companion' button type to reduce number of buttons needed. Make trims work via buttons in USB joystick.

* Connect joystick trim buttons to simulator widgets.

* Use companion source names for trims.

* Add encode / decode of usb joystick custom settings to Companion.

* Convert to lvgl layouts.
Update language files.

* Fix generated YAML storage files.

* Fix initialisation error when editing button channel. Cleanup code.

* Fix rebase.

* Fix refresh of joystick channel list view after editing an entry.
Companion joystick config window uses two columns.

* Fix vertical joystick inversion bug.
Change stick axis labels.

---------

Co-authored-by: Phil Mitchell <phil.a.mitchell@gmail.com>
This commit is contained in:
philmoz
2023-03-22 10:31:29 +10:00
committed by GitHub
co-authored by Phil Mitchell
parent a1178f83a6
commit 661657feca
81 changed files with 3501 additions and 572 deletions
+63 -10
View File
@@ -21,7 +21,6 @@
#include "simulatorwidget.h"
#include "ui_simulatorwidget.h"
#include "appdata.h"
#include "appdebugmessagehandler.h"
#include "radiofaderwidget.h"
#include "radiokeywidget.h"
@@ -619,7 +618,6 @@ void SimulatorWidget::setupRadioWidgets()
RadioKnobWidget * pot = new RadioKnobWidget(Board::PotType(radioSettings.potConfig[i]), wname, 0, ui->radioWidgetsHT);
pot->setIndex(i);
ui->radioWidgetsHTLayout->insertWidget(midpos++, pot);
m_radioWidgets.append(pot);
}
@@ -661,6 +659,7 @@ void SimulatorWidget::setupRadioWidgets()
foreach (RadioWidget * rw, m_radioWidgets) {
connect(rw, &RadioWidget::valueChange, this, &SimulatorWidget::onRadioWidgetValueChange);
connect(this, &SimulatorWidget::widgetValueChange, rw, &RadioWidget::setValueQual);
connect(this, &SimulatorWidget::widgetValueAdjust, rw, &RadioWidget::chgValueQual);
connect(this, &SimulatorWidget::widgetStateChange, rw, &RadioWidget::setStateData);
}
@@ -673,21 +672,28 @@ void SimulatorWidget::setupJoysticks()
if (g.jsSupport() && g.jsCtrl() > -1) {
if (!joystick)
joystick = new Joystick(this);
joystick = new Joystick(this, SDL_JOYSTICK_DEFAULT_EVENT_TIMEOUT, false, SDL_JOYSTICK_DEFAULT_AUTOREPEAT_DELAY);
else
joystick->close();
if (joystick && joystick->open(g.jsCtrl())) {
int numAxes = std::min(joystick->numAxes, MAX_JOYSTICKS);
int numAxes = std::min(joystick->numAxes, MAX_JS_AXES);
for (int j=0; j<numAxes; j++) {
joystick->sensitivities[j] = 0;
joystick->deadzones[j] = 0;
}
connect(joystick, &Joystick::axisValueChanged, this, &SimulatorWidget::onjoystickAxisValueChanged);
if (vJoyLeft)
connect(joystick, &Joystick::buttonValueChanged, this, &SimulatorWidget::onjoystickButtonValueChanged);
if (vJoyLeft) {
connect(this, &SimulatorWidget::stickValueChange, vJoyLeft, &VirtualJoystickWidget::setStickAxisValue);
if (vJoyRight)
connect(this, &SimulatorWidget::widgetValueAdjust, vJoyLeft->horizontalTrim(), &RadioWidget::chgValueQual);
connect(this, &SimulatorWidget::widgetValueAdjust, vJoyLeft->verticalTrim(), &RadioWidget::chgValueQual);
}
if (vJoyRight) {
connect(this, &SimulatorWidget::stickValueChange, vJoyRight, &VirtualJoystickWidget::setStickAxisValue);
connect(this, &SimulatorWidget::widgetValueAdjust, vJoyRight->horizontalTrim(), &RadioWidget::chgValueQual);
connect(this, &SimulatorWidget::widgetValueAdjust, vJoyRight->verticalTrim(), &RadioWidget::chgValueQual);
}
joysticksEnabled = true;
}
else {
@@ -858,7 +864,7 @@ void SimulatorWidget::onjoystickAxisValueChanged(int axis, int value)
static const int ttlFaders = Boards::getCapability(m_board, Board::Sliders);
static const int valueRange = 1024;
if (!joystick || axis >= MAX_JOYSTICKS)
if (!joystick || axis >= MAX_JS_AXES)
return;
int dlta;
@@ -885,11 +891,58 @@ void SimulatorWidget::onjoystickAxisValueChanged(int axis, int value)
}
else {
stick -= ttlSticks;
if (stick < ttlKnobs)
if (stick < ttlKnobs) {
GeneralSettings radioSettings = GeneralSettings();
if (Board::PotType(radioSettings.potConfig[stick]) == Board::POT_MULTIPOS_SWITCH)
stickval += 1024;
emit widgetValueChange(RadioWidget::RADIO_WIDGET_KNOB, stick, stickval);
else
emit widgetValueChange(RadioWidget::RADIO_WIDGET_FADER, stick - ttlKnobs, stickval);
} else {
stick -= ttlKnobs;
emit widgetValueChange(RadioWidget::RADIO_WIDGET_FADER, stick, stickval);
}
}
#endif
}
void SimulatorWidget::onjoystickButtonValueChanged(int button, bool state)
{
#ifdef JOYSTICKS
if (!joystick || button >= MAX_JS_BUTTONS)
return;
int ttlSwitches = Boards::getCapability(m_board, Board::Switches);
int btn = g.jsButton[button].button_idx();
if (g.jsButton[button].button_inv())
state = !state;
int swtch = btn & JS_BUTTON_SWITCH_MASK;
if (swtch < ttlSwitches) {
if (btn & JS_BUTTON_3POS_DN) {
// 3POS Down
if (state || (switchDirection[swtch] == 0) || (switchDirection[swtch] == (btn & JS_BUTTON_TYPE_MASK))) {
emit widgetValueChange(RadioWidget::RADIO_WIDGET_SWITCH, swtch, state ? 1 : 0);
switchDirection[swtch] = (btn & JS_BUTTON_TYPE_MASK);
}
} else if (btn & JS_BUTTON_3POS_UP) {
// 3POS Up
if (state || (switchDirection[swtch] == 0) || (switchDirection[swtch] == (btn & JS_BUTTON_TYPE_MASK))) {
emit widgetValueChange(RadioWidget::RADIO_WIDGET_SWITCH, swtch, state ? -1 : 0);
switchDirection[swtch] = (btn & JS_BUTTON_TYPE_MASK);
}
} else if (btn & JS_BUTTON_TOGGLE) {
// Toggle or momentary
emit widgetValueChange(RadioWidget::RADIO_WIDGET_SWITCH, swtch, state ? 1 : - 1);
}
} else {
// Trim
swtch -= ttlSwitches;
int offset = (btn & JS_BUTTON_3POS_DN) ? -1 : 1;
emit widgetValueAdjust(RadioWidget::RADIO_WIDGET_TRIM, swtch, offset, state);
}
#endif
}