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:
@@ -273,7 +273,7 @@ void AppPreferencesDialog::initSettings()
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
QStringList joystickNames;
|
||||
joystickNames << tr("No joysticks found");
|
||||
joystick = new Joystick(0,false,0,0);
|
||||
joystick = new Joystick(0,0,false,0);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
ui->joystickCB->setDisabled(true);
|
||||
|
||||
@@ -591,7 +591,7 @@ void AppPreferencesDialog::on_joystickChkB_clicked() {
|
||||
if (ui->joystickChkB->isChecked()) {
|
||||
QStringList joystickNames;
|
||||
joystickNames << tr("No joysticks found");
|
||||
joystick = new Joystick(0,false,0,0);
|
||||
joystick = new Joystick(0,0,false,0);
|
||||
ui->joystickcalButton->setDisabled(true);
|
||||
ui->joystickCB->setDisabled(true);
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ set(firmwares_SRCS
|
||||
edgetx/yaml_customfunctiondata.cpp
|
||||
edgetx/yaml_sensordata.cpp
|
||||
edgetx/yaml_screendata.cpp
|
||||
edgetx/yaml_usbjoystickdata.cpp
|
||||
datahelpers.cpp
|
||||
customisation_data.cpp
|
||||
)
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "yaml_customfunctiondata.h"
|
||||
#include "yaml_sensordata.h"
|
||||
#include "yaml_screendata.h"
|
||||
#include "yaml_usbjoystickdata.h"
|
||||
|
||||
#include "modeldata.h"
|
||||
#include "output_data.h"
|
||||
@@ -79,6 +80,12 @@ static const YamlLookupTable jitterFilterLut = {
|
||||
{ 2, "ON" },
|
||||
};
|
||||
|
||||
static const YamlLookupTable usbJoystickIfModeLut = {
|
||||
{ 0, "JOYSTICK" },
|
||||
{ 1, "GAMEPAD" },
|
||||
{ 2, "MULTIAXIS" },
|
||||
};
|
||||
|
||||
struct YamlTrim {
|
||||
int mode = 0;
|
||||
int ref = 0;
|
||||
@@ -1008,6 +1015,16 @@ Node convert<ModelData>::encode(const ModelData& rhs)
|
||||
}
|
||||
}
|
||||
|
||||
// Custom USB joytsick mapping
|
||||
node["usbJoystickExtMode"] = rhs.usbJoystickExtMode;
|
||||
node["usbJoystickIfMode"] = usbJoystickIfModeLut << rhs.usbJoystickIfMode;
|
||||
node["usbJoystickCircularCut"] = rhs.usbJoystickCircularCut;
|
||||
for (int i = 0; i < CPN_USBJ_MAX_JOYSTICK_CHANNELS; i++) {
|
||||
if (rhs.usbJoystickCh[i].mode > 0) {
|
||||
node["usbJoystickCh"][std::to_string(i)] = rhs.usbJoystickCh[i];
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
@@ -1194,6 +1211,12 @@ bool convert<ModelData>::decode(const Node& node, ModelData& rhs)
|
||||
node["functionSwitchLogicalState"] >> rhs.functionSwitchLogicalState;
|
||||
node["switchNames"] >> rhs.functionSwitchNames;
|
||||
|
||||
// Custom USB joytsick mapping
|
||||
node["usbJoystickExtMode"] >> rhs.usbJoystickExtMode;
|
||||
node["usbJoystickIfMode"] >> usbJoystickIfModeLut >> rhs.usbJoystickIfMode;
|
||||
node["usbJoystickCircularCut"] >> rhs.usbJoystickCircularCut;
|
||||
node["usbJoystickCh"] >> rhs.usbJoystickCh;
|
||||
|
||||
// preferably perform conversions here to avoid cluttering the field decodes
|
||||
|
||||
if (SemanticVersion(QString(rhs.semver)) < SemanticVersion("2.8.0")) {
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* 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 "yaml_usbjoystickdata.h"
|
||||
#include "generalsettings.h"
|
||||
#include "modeldata.h"
|
||||
|
||||
const YamlLookupTable usbJoystickChMode = {
|
||||
{0, "CH_NONE"},
|
||||
{1, "CH_BUTTON"},
|
||||
{2, "CH_AXIS"},
|
||||
{3, "CH_SIM"},
|
||||
};
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
|
||||
Node convert<USBJoystickChData>::encode(const USBJoystickChData& rhs)
|
||||
{
|
||||
Node node;
|
||||
node["mode"] = usbJoystickChMode << rhs.mode;
|
||||
node["inversion"] = rhs.inversion;
|
||||
node["param"] = rhs.param;
|
||||
node["btn_num"] = rhs.btn_num;
|
||||
node["switch_npos"] = rhs.switch_npos;
|
||||
return node;
|
||||
}
|
||||
|
||||
bool convert<USBJoystickChData>::decode(const Node& node, USBJoystickChData& rhs)
|
||||
{
|
||||
node["mode"] >> usbJoystickChMode >> rhs.mode;
|
||||
node["inversion"] >> rhs.inversion;
|
||||
node["param"] >> rhs.param;
|
||||
node["btn_num"] >> rhs.btn_num;
|
||||
node["switch_npos"] >> rhs.switch_npos;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace YAML
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* 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 "yaml_ops.h"
|
||||
#include "generalsettings.h"
|
||||
|
||||
extern const YamlLookupTable usbJoystickChMode;
|
||||
|
||||
class USBJoystickChData;
|
||||
|
||||
namespace YAML
|
||||
{
|
||||
template <>
|
||||
struct convert<USBJoystickChData> {
|
||||
static Node encode(const USBJoystickChData& rhs);
|
||||
static bool decode(const Node& node, USBJoystickChData& rhs);
|
||||
};
|
||||
} // namespace YAML
|
||||
@@ -90,6 +90,19 @@ enum TrainerMode {
|
||||
#define INPUT_NAME_LEN 4
|
||||
#define CPN_MAX_BITMAP_LEN 14
|
||||
|
||||
#define CPN_USBJ_MAX_JOYSTICK_CHANNELS 26
|
||||
|
||||
class USBJoystickChData {
|
||||
public:
|
||||
USBJoystickChData() { clear(); }
|
||||
unsigned int mode;
|
||||
unsigned int inversion;
|
||||
unsigned int param;
|
||||
unsigned int btn_num;
|
||||
unsigned int switch_npos;
|
||||
void clear() { memset(reinterpret_cast<void *>(this), 0, sizeof(USBJoystickChData)); }
|
||||
};
|
||||
|
||||
class ModelData {
|
||||
Q_DECLARE_TR_FUNCTIONS(ModelData)
|
||||
|
||||
@@ -201,6 +214,12 @@ class ModelData {
|
||||
unsigned int functionSwitchLogicalState;
|
||||
char functionSwitchNames[CPN_MAX_FUNCTION_SWITCHES][HARDWARE_NAME_LEN + 1];
|
||||
|
||||
// Custom USB joytsick mapping
|
||||
unsigned int usbJoystickExtMode;
|
||||
unsigned int usbJoystickIfMode;
|
||||
unsigned int usbJoystickCircularCut;
|
||||
USBJoystickChData usbJoystickCh[CPN_USBJ_MAX_JOYSTICK_CHANNELS];
|
||||
|
||||
void clear();
|
||||
bool isEmpty() const;
|
||||
void setDefaultInputs(const GeneralSettings & settings);
|
||||
|
||||
@@ -116,7 +116,7 @@ qreal Node::getY()
|
||||
if(scene())
|
||||
{
|
||||
QRectF rect = scene()->sceneRect();
|
||||
return 1+((y()-rect.bottom())*2/rect.height());
|
||||
return ((rect.bottom()-y())*2/rect.height())-1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ void Node::setY(qreal newY)
|
||||
if(scene())
|
||||
{
|
||||
QRectF rect = scene()->sceneRect();
|
||||
QGraphicsObject::setY(rect.top() + (newY+1) * rect.height()/2);
|
||||
QGraphicsObject::setY(rect.top() + (1-newY) * rect.height()/2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,6 +63,9 @@ bool Joystick::open(int stick)
|
||||
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 {
|
||||
@@ -109,9 +112,9 @@ void Joystick::processEvents()
|
||||
axisRepeatTimers[i].restart();
|
||||
}
|
||||
}
|
||||
else {
|
||||
emit axisValueChanged(i, 0);
|
||||
}
|
||||
// else {
|
||||
// emit axisValueChanged(i, 0);
|
||||
// }
|
||||
}
|
||||
for (i = 0; i < numButtons; i++) {
|
||||
Uint8 changed = SDL_JoystickGetButton(joystick, i);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "joystickdialog.h"
|
||||
#include "ui_joystickdialog.h"
|
||||
#include "eeprominterface.h"
|
||||
|
||||
#include "boards.h"
|
||||
#include "constants.h"
|
||||
@@ -33,40 +34,71 @@ joystickDialog::joystickDialog(QWidget *parent, int stick) :
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
int jscaltmp[8][3] = {
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767},
|
||||
{32767, 0, -32767}
|
||||
};
|
||||
memcpy(jscal, jscaltmp, sizeof (jscal));
|
||||
int i;
|
||||
char s[20];
|
||||
|
||||
foreach(QComboBox *cb, findChildren<QComboBox *>(QRegularExpression("jsmapCB_[0-9]+"))) {
|
||||
populateSourceCombo(cb);
|
||||
sticks[cb->property("channel").toUInt()] = cb;
|
||||
}
|
||||
foreach(QCheckBox *ib, findChildren<QCheckBox *>(QRegularExpression("ChInv_[0-9]+"))) {
|
||||
invert[ib->property("channel").toUInt()] = ib;
|
||||
}
|
||||
foreach(QSlider *sl, findChildren<QSlider *>(QRegularExpression("Ch_[0-9]+"))) {
|
||||
sliders[sl->property("channel").toUInt()] = sl;
|
||||
for (i = 0; i < MAX_JS_AXES; i += 1) {
|
||||
jscal[i][0] = 32767;
|
||||
jscal[i][1] = 0;
|
||||
jscal[i][2] = -32767;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_JOYSTICKS; ++i) {
|
||||
if (!g.joystick[i].existsOnDisk())
|
||||
continue;
|
||||
QGridLayout *grid = findChild<QGridLayout*>("gridLayout");
|
||||
int row = 0;
|
||||
int col = 0;
|
||||
if (grid) {
|
||||
for (i = 0; i < MAX_JS_AXES; i += 1, row += 1) {
|
||||
col = (i & 1) * 4;
|
||||
sprintf(s, "Ch%d", i + 1);
|
||||
QLabel *l = new QLabel(s);
|
||||
grid->addWidget(l, row/2, col+0, 1, 1);
|
||||
QSlider *s = new QSlider(Qt::Horizontal);
|
||||
s->setMinimum(-32767);
|
||||
s->setMaximum(32767);
|
||||
sliders[row] = s;
|
||||
grid->addWidget(s, row/2, col+1, 1, 1);
|
||||
QCheckBox *c = new QCheckBox("");
|
||||
invert[row] = c;
|
||||
grid->addWidget(c, row/2, col+2, 1, 1);
|
||||
QComboBox *d = new QComboBox();
|
||||
populateSourceCombo(d);
|
||||
sticks[row] = d;
|
||||
grid->addWidget(d, row/2, col+3, 1, 1);
|
||||
}
|
||||
if (row & 1) row += 1;
|
||||
for (i = 0; i < MAX_JS_BUTTONS; i += 1, row += 1) {
|
||||
col = (i & 1) * 4;
|
||||
sprintf(s, "Btn%d", i + 1);
|
||||
QLabel *l = new QLabel(s);
|
||||
grid->addWidget(l, row/2, col+0, 1, 1);
|
||||
QSlider *s = new QSlider(Qt::Horizontal);
|
||||
s->setMinimum(0);
|
||||
s->setMaximum(1);
|
||||
sliders[row] = s;
|
||||
grid->addWidget(s, row/2, col+1, 1, 1);
|
||||
QComboBox *d = new QComboBox();
|
||||
populateButtonCombo(d);
|
||||
sticks[row] = d;
|
||||
grid->addWidget(d, row/2, col+3, 1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
jscal[i][0] = g.joystick[i].stick_min();
|
||||
jscal[i][1] = g.joystick[i].stick_med();
|
||||
jscal[i][2] = g.joystick[i].stick_max();
|
||||
sliders[i]->setMinimum(jscal[i][0]);
|
||||
sliders[i]->setMaximum(jscal[i][2]);
|
||||
invert[i]->setChecked(g.joystick[i].stick_inv());
|
||||
sticks[i]->setCurrentIndex(sticks[i]->findData(g.joystick[i].stick_axe()));
|
||||
for (int i = 0; i < MAX_JS_AXES; ++i) {
|
||||
if (g.joystick[i].existsOnDisk()) {
|
||||
jscal[i][0] = g.joystick[i].stick_min();
|
||||
jscal[i][1] = g.joystick[i].stick_med();
|
||||
jscal[i][2] = g.joystick[i].stick_max();
|
||||
sliders[i]->setMinimum(jscal[i][0]);
|
||||
sliders[i]->setMaximum(jscal[i][2]);
|
||||
invert[i]->setChecked(g.joystick[i].stick_inv());
|
||||
sticks[i]->setCurrentIndex(sticks[i]->findData(g.joystick[i].stick_axe()));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_JS_BUTTONS; ++i) {
|
||||
if (g.jsButton[i].existsOnDisk()) {
|
||||
sticks[i+MAX_JS_AXES]->setCurrentIndex(sticks[i+MAX_JS_AXES]->findData(g.jsButton[i].button_idx()));
|
||||
}
|
||||
}
|
||||
|
||||
ui->backButton->setEnabled(false);
|
||||
@@ -86,6 +118,7 @@ joystickDialog::joystickDialog(QWidget *parent, int stick) :
|
||||
loadStep();
|
||||
|
||||
connect(joystick, SIGNAL(axisValueChanged(int, int)), this, SLOT(onjoystickAxisValueChanged(int, int)));
|
||||
connect(joystick, SIGNAL(buttonValueChanged(int, bool)), this, SLOT(onjoystickButtonValueChanged(int, bool)));
|
||||
connect(ui->joystickCB, SIGNAL(currentIndexChanged(int)), this, SLOT(joystickOpen(int)));
|
||||
connect(ui->joystickChkB, SIGNAL(toggled(bool)), this, SLOT(joystickSetEnabled(bool)));
|
||||
}
|
||||
@@ -98,13 +131,75 @@ joystickDialog::~joystickDialog()
|
||||
void joystickDialog::populateSourceCombo(QComboBox * cb)
|
||||
{
|
||||
int i;
|
||||
QString wname;
|
||||
|
||||
Board::Type m_board = getCurrentBoard();
|
||||
GeneralSettings radioSettings = GeneralSettings();
|
||||
|
||||
int ttlSticks = Boards::getCapability(m_board, Board::Sticks);
|
||||
int ttlKnobs = Boards::getCapability(m_board, Board::Pots);
|
||||
int ttlFaders = Boards::getCapability(m_board, Board::Sliders);
|
||||
|
||||
cb->clear();
|
||||
cb->addItem(tr("Not Assigned"), -1);
|
||||
for (i=0; i < Board::STICK_AXIS_COUNT; ++i) {
|
||||
cb->addItem(Boards::getAxisName(i) % tr(" Stick"), i);
|
||||
|
||||
for (i=0; i < ttlSticks; ++i) {
|
||||
wname = Boards::getAxisName(i);
|
||||
cb->addItem(wname, i);
|
||||
}
|
||||
for (; i < Board::STICK_AXIS_COUNT + CPN_MAX_POTS + CPN_MAX_SLIDERS; ++i) {
|
||||
cb->addItem(tr("Knob/Slider %1").arg(i - Board::STICK_AXIS_COUNT + 1), i);
|
||||
|
||||
for (i = 0; i < ttlKnobs; ++i) {
|
||||
if (radioSettings.isPotAvailable(i)) {
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + i).toString(nullptr, &radioSettings);
|
||||
cb->addItem(wname, i + ttlSticks);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ttlFaders; ++i) {
|
||||
if (radioSettings.isSliderAvailable(i)) {
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_STICK, ttlSticks + ttlKnobs + i).toString(nullptr, &radioSettings);
|
||||
cb->addItem(wname, i + ttlSticks + ttlKnobs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void joystickDialog::populateButtonCombo(QComboBox * cb)
|
||||
{
|
||||
int i;
|
||||
QString wname;
|
||||
|
||||
Board::Type m_board = getCurrentBoard();
|
||||
GeneralSettings radioSettings = GeneralSettings();
|
||||
|
||||
int ttlSwitches = Boards::getCapability(m_board, Board::Switches);
|
||||
int ttlTrims = Boards::getCapability(m_board, Board::NumTrims);
|
||||
|
||||
cb->clear();
|
||||
cb->addItem(tr("Not Assigned"), -1);
|
||||
|
||||
Board::SwitchType swcfg;
|
||||
for (i = 0; i < ttlSwitches; ++i) {
|
||||
if (radioSettings.switchConfig[i] != Board::SWITCH_NOT_AVAILABLE) {
|
||||
swcfg = Board::SwitchType(radioSettings.switchConfig[i]);
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_SWITCH, i).toString(nullptr, &radioSettings);
|
||||
if (swcfg == Board::SWITCH_3POS) {
|
||||
cb->addItem(wname + CPN_STR_SW_INDICATOR_UP, i | JS_BUTTON_3POS_UP);
|
||||
cb->addItem(wname + CPN_STR_SW_INDICATOR_DN, i | JS_BUTTON_3POS_DN);
|
||||
} else {
|
||||
cb->addItem(wname, i | JS_BUTTON_TOGGLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ttlTrims; i += 1) {
|
||||
wname = RawSource(RawSourceType::SOURCE_TYPE_TRIM, i).toString(nullptr, &radioSettings);
|
||||
if ((i == 0) || (i == 3)) {
|
||||
cb->addItem(wname + " Left", i + ttlSwitches | JS_BUTTON_3POS_DN);
|
||||
cb->addItem(wname + " Right", i + ttlSwitches | JS_BUTTON_3POS_UP);
|
||||
} else {
|
||||
cb->addItem(wname + " Down", i + ttlSwitches | JS_BUTTON_3POS_DN);
|
||||
cb->addItem(wname + " Up", i + ttlSwitches | JS_BUTTON_3POS_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +210,7 @@ bool joystickDialog::loadJoysticks(int stick)
|
||||
|
||||
ui->joystickCB->clear();
|
||||
joystickNames << tr("No joysticks found");
|
||||
joystick = new Joystick(0, false, 0, 0);
|
||||
joystick = new Joystick(0, 0, false, 0);
|
||||
if ( joystick ) {
|
||||
if ( joystick->joystickNames.count() > 0 ) {
|
||||
joystickNames = joystick->joystickNames;
|
||||
@@ -140,10 +235,10 @@ void joystickDialog::joystickOpen(int stick)
|
||||
|
||||
joystick = new Joystick(this, 1, false, 0);
|
||||
if (joystick && joystick->open(stick)) {
|
||||
numAxes = std::min(joystick->numAxes, MAX_JOYSTICKS);
|
||||
numAxes = std::min(joystick->numAxes, MAX_JS_AXES);
|
||||
for (int j=0; j<numAxes; j++) {
|
||||
joystick->sensitivities[j] = 0;
|
||||
joystick->deadzones[j]=20;
|
||||
joystick->deadzones[j] = 20;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -161,7 +256,7 @@ void joystickDialog::joystickSetEnabled(bool enable)
|
||||
|
||||
void joystickDialog::onjoystickAxisValueChanged(int axis, int value)
|
||||
{
|
||||
if (axis >= MAX_JOYSTICKS)
|
||||
if (axis >= MAX_JS_AXES)
|
||||
return;
|
||||
|
||||
if (started) {
|
||||
@@ -177,6 +272,14 @@ void joystickDialog::onjoystickAxisValueChanged(int axis, int value)
|
||||
sliders[axis]->setValue(value);
|
||||
}
|
||||
|
||||
void joystickDialog::onjoystickButtonValueChanged(int button, bool state)
|
||||
{
|
||||
if (button >= MAX_JS_BUTTONS)
|
||||
return;
|
||||
|
||||
sliders[button + MAX_JS_AXES]->setValue(state);
|
||||
}
|
||||
|
||||
void joystickDialog::loadStep()
|
||||
{
|
||||
switch (step) {
|
||||
@@ -241,8 +344,6 @@ void joystickDialog::on_cancelButton_clicked()
|
||||
|
||||
void joystickDialog::on_okButton_clicked()
|
||||
{
|
||||
int stick;
|
||||
|
||||
g.jsSupport(ui->joystickChkB->isChecked());
|
||||
g.jsCtrl(ui->joystickCB->currentIndex());
|
||||
|
||||
@@ -261,8 +362,8 @@ void joystickDialog::on_okButton_clicked()
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_JOYSTICKS; ++i) {
|
||||
stick = sticks[i]->currentData().toInt();
|
||||
for (int i = 0; i < MAX_JS_AXES; ++i) {
|
||||
auto stick = sticks[i]->currentData().toInt();
|
||||
if (stick < 0) {
|
||||
g.joystick[i].stick_axe(-1);
|
||||
}
|
||||
@@ -276,5 +377,16 @@ void joystickDialog::on_okButton_clicked()
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_JS_BUTTONS; ++i) {
|
||||
auto btn = sticks[i+MAX_JS_AXES]->currentData().toInt();
|
||||
if (btn < 0) {
|
||||
g.jsButton[i].button_idx(-1);
|
||||
}
|
||||
else {
|
||||
g.jsButton[i].button_idx(btn);
|
||||
qDebug() << "joystick button mapping " << sticks[i+MAX_JS_AXES]->objectName() << "stick:" << i << "idx:" << btn;
|
||||
}
|
||||
}
|
||||
|
||||
this->accept();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,14 @@ class QCheckBox;
|
||||
class QComboBox;
|
||||
class QSlider;
|
||||
|
||||
enum JSButtonFlag {
|
||||
JS_BUTTON_TOGGLE = 0x1000,
|
||||
JS_BUTTON_3POS_UP = 0x2000,
|
||||
JS_BUTTON_3POS_DN = 0x4000,
|
||||
JS_BUTTON_TYPE_MASK = 0xF000,
|
||||
JS_BUTTON_SWITCH_MASK = 0x1F
|
||||
};
|
||||
|
||||
namespace Ui {
|
||||
class joystickDialog;
|
||||
}
|
||||
@@ -44,20 +52,22 @@ class joystickDialog : public QDialog
|
||||
|
||||
private:
|
||||
Ui::joystickDialog *ui;
|
||||
int jscal[MAX_JOYSTICKS][3];
|
||||
QCheckBox * invert[MAX_JOYSTICKS];
|
||||
QComboBox * sticks[MAX_JOYSTICKS];
|
||||
QSlider * sliders[MAX_JOYSTICKS];
|
||||
int jscal[MAX_JS_AXES][3];
|
||||
QCheckBox * invert[MAX_JS_AXES];
|
||||
QComboBox * sticks[MAX_JS_AXES + MAX_JS_BUTTONS];
|
||||
QSlider * sliders[MAX_JS_AXES + MAX_JS_BUTTONS];
|
||||
int step;
|
||||
int numAxes;
|
||||
bool started;
|
||||
|
||||
private slots:
|
||||
void populateSourceCombo(QComboBox * cb);
|
||||
void populateButtonCombo(QComboBox * cb);
|
||||
bool loadJoysticks(int stick = -1);
|
||||
void joystickOpen(int stick);
|
||||
void joystickSetEnabled(bool enable);
|
||||
void onjoystickAxisValueChanged(int axis, int value);
|
||||
void onjoystickButtonValueChanged(int button, bool state);
|
||||
void loadStep();
|
||||
void on_backButton_clicked();
|
||||
void on_nextButton_clicked();
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>554</width>
|
||||
<height>351</height>
|
||||
<width>709</width>
|
||||
<height>195</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -20,495 +20,23 @@
|
||||
<string>Configure Joystick</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="2" rowspan="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QWidget" name="calibrationWidget" native="true">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>640</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Ch2</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QSlider" name="Ch_3">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Ch1</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_3">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSlider" name="Ch_2">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_1">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Ch4</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QSlider" name="Ch_5">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Ch6</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Ch3</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_5">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QSlider" name="Ch_4">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_4">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QSlider" name="Ch_6">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_6">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Ch5</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Ch7</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QSlider" name="Ch_7">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_7">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>Ch8</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QSlider" name="Ch_8">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="3">
|
||||
<widget class="QComboBox" name="jsmapCB_8">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QSlider" name="Ch_1">
|
||||
<property name="minimum">
|
||||
<number>-32767</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>32676</number>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="invertedAppearance">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="invertedControls">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="tickPosition">
|
||||
<enum>QSlider::NoTicks</enum>
|
||||
</property>
|
||||
<property name="tickInterval">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_1">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_2">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_3">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>2</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_4">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_5">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>4</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_6">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>5</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_7">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>6</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QCheckBox" name="ChInv_8">
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
<property name="channel" stdset="0">
|
||||
<number>7</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QGridLayout" name="gridLayout"/>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="howtoLabel">
|
||||
@@ -544,6 +72,19 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2" rowspan="4">
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
@@ -587,7 +128,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>198</width>
|
||||
<width>360</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -647,7 +188,7 @@
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<width>1</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
@@ -661,7 +202,7 @@
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
<height>1</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#ifndef _SIMULATORWIDGET_H_
|
||||
#define _SIMULATORWIDGET_H_
|
||||
|
||||
#include "appdata.h"
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "radiodata.h"
|
||||
@@ -88,6 +89,7 @@ class SimulatorWidget : public QWidget
|
||||
void stickValueChange(int axis, int value);
|
||||
void stickModeChange(const unsigned mode);
|
||||
void widgetValueChange(const RadioWidget::RadioWidgetType type, const int index, const int value);
|
||||
void widgetValueAdjust(const RadioWidget::RadioWidgetType type, const int index, const int offset, const bool state);
|
||||
void widgetStateChange(const RadioWidget::RadioWidgetState & state);
|
||||
void inputValueChange(int type, quint8 index, qint16 value);
|
||||
void simulatorSetData(const QByteArray & data);
|
||||
@@ -110,6 +112,7 @@ class SimulatorWidget : public QWidget
|
||||
void onSimulatorError(const QString & error);
|
||||
void onRadioWidgetValueChange(const RadioWidget::RadioWidgetType type, const int index, int value);
|
||||
void onjoystickAxisValueChanged(int axis, int value);
|
||||
void onjoystickButtonValueChanged(int button, bool state);
|
||||
|
||||
void setRadioProfileId(int value);
|
||||
void setupRadioWidgets();
|
||||
@@ -145,6 +148,7 @@ class SimulatorWidget : public QWidget
|
||||
|
||||
#ifdef JOYSTICKS
|
||||
Joystick * joystick = nullptr;
|
||||
int switchDirection[MAX_JS_BUTTONS];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ class RadioTrimWidget : public RadioWidget
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
void setValue(const int & value)
|
||||
void setValue(const int & value) override
|
||||
{
|
||||
if (sender() && qobject_cast<SliderWidget *>(sender())) {
|
||||
RadioWidget::setValue(value);
|
||||
@@ -75,6 +75,12 @@ class RadioTrimWidget : public RadioWidget
|
||||
}
|
||||
}
|
||||
|
||||
void chgValueQual(const RadioWidgetType & type, const int & index, const int offset, const bool state) override {
|
||||
if (type == m_type && index == m_index) {
|
||||
emit valueChange(m_type, (offset < 0) ? m_btnDecIndex : m_btnIncIndex, state ? RADIO_TRIM_BTN_ON : RADIO_TRIM_BTN_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
protected slots:
|
||||
|
||||
void init(Qt::Orientation orientation)
|
||||
|
||||
@@ -88,6 +88,7 @@ class RadioWidget : public QWidget
|
||||
virtual void setType(const RadioWidgetType & type);
|
||||
virtual void setValue(const int & value);
|
||||
virtual void setValueQual(const RadioWidgetType & type, const int & index, const int & value);
|
||||
virtual void chgValueQual(const RadioWidgetType & type, const int & index, const int offset, const bool state) {}
|
||||
virtual void setFlags(const quint16 & flags);
|
||||
virtual void setShowLabel(const bool show);
|
||||
virtual void setLabelText(const QString & labelText, bool showLabel = true);
|
||||
|
||||
@@ -323,7 +323,7 @@ void VirtualJoystickWidget::onNodeXChanged()
|
||||
|
||||
void VirtualJoystickWidget::onNodeYChanged()
|
||||
{
|
||||
emit valueChange(RadioWidget::RADIO_WIDGET_STICK, m_yIndex, int(-m_stickScale * getStickY()));
|
||||
emit valueChange(RadioWidget::RADIO_WIDGET_STICK, m_yIndex, int(m_stickScale * getStickY()));
|
||||
updateNodeValueLabels();
|
||||
}
|
||||
|
||||
@@ -564,9 +564,9 @@ void VirtualJoystickWidget::onButtonChange(bool checked)
|
||||
void VirtualJoystickWidget::updateNodeValueLabels()
|
||||
{
|
||||
if (nodeLabelX)
|
||||
nodeLabelX->setText(QString("%1").arg(node->getX() * 100.0f, 2, 'f', 0));
|
||||
nodeLabelX->setText(QString("%1").arg(getStickX() * 100.0f, 2, 'f', 0));
|
||||
if (nodeLabelY)
|
||||
nodeLabelY->setText(QString("%1").arg(node->getY() * -100.0f, 2, 'f', 0));
|
||||
nodeLabelY->setText(QString("%1").arg(getStickY() * 100.0f, 2, 'f', 0));
|
||||
}
|
||||
|
||||
void VirtualJoystickWidget::onGsMouseEvent(QGraphicsSceneMouseEvent * event)
|
||||
|
||||
@@ -61,6 +61,9 @@ class VirtualJoystickWidget : public QWidget
|
||||
int getStickScale() const;
|
||||
void setStickScale(int stickScale);
|
||||
|
||||
const RadioTrimWidget *horizontalTrim() { return hTrimWidget; }
|
||||
const RadioTrimWidget *verticalTrim() { return vTrimWidget; }
|
||||
|
||||
public slots:
|
||||
void setStickX(qreal x);
|
||||
void setStickY(qreal y);
|
||||
|
||||
@@ -256,6 +256,16 @@ bool JStickData::existsOnDisk()
|
||||
return (m_settings.value(settingsPath() % stick_axe_key(), -1).toInt() > -1);
|
||||
}
|
||||
|
||||
JButtonData::JButtonData() : CompStoreObj(), index(-1)
|
||||
{
|
||||
CompStoreObj::addObjectMapping(propertyGroup(), this);
|
||||
}
|
||||
|
||||
bool JButtonData::existsOnDisk()
|
||||
{
|
||||
return (m_settings.value(settingsPath() % button_idx_key(), -1).toInt() > -1);
|
||||
}
|
||||
|
||||
|
||||
// ** Profile class********************
|
||||
|
||||
@@ -397,8 +407,10 @@ AppData::AppData() :
|
||||
profile[i].setIndex(i);
|
||||
|
||||
// Configure the joysticks
|
||||
for (int i = 0; i < MAX_JOYSTICKS; i++)
|
||||
for (int i = 0; i < MAX_JS_AXES; i++)
|
||||
joystick[i].setIndex(i);
|
||||
for (int i = 0; i < MAX_JS_BUTTONS; i++)
|
||||
jsButton[i].setIndex(i);
|
||||
|
||||
// Configure the updates
|
||||
for (int i = 0; i < MAX_COMPONENTS; i++) {
|
||||
@@ -436,8 +448,10 @@ void AppData::initAll()
|
||||
for (int i = 0; i < MAX_PROFILES; i++)
|
||||
profile[i].init();
|
||||
// Initialize the joysticks
|
||||
for (int i = 0; i < MAX_JOYSTICKS; i++)
|
||||
for (int i = 0; i < MAX_JS_AXES; i++)
|
||||
joystick[i].init();
|
||||
for (int i = 0; i < MAX_JS_BUTTONS; i++)
|
||||
jsButton[i].init();
|
||||
// Initialize the updatess
|
||||
for (int i = 0; i < MAX_COMPONENTS; i++) {
|
||||
component[i].init();
|
||||
@@ -453,8 +467,10 @@ void AppData::resetAllSettings()
|
||||
fwRev.resetAll();
|
||||
for (int i = 0; i < MAX_PROFILES; i++)
|
||||
profile[i].resetAll();
|
||||
for (int i = 0; i < MAX_JOYSTICKS; i++)
|
||||
for (int i = 0; i < MAX_JS_AXES; i++)
|
||||
joystick[i].resetAll();
|
||||
for (int i = 0; i < MAX_JS_BUTTONS; i++)
|
||||
jsButton[i].resetAll();
|
||||
for (int i = 0; i < MAX_COMPONENTS; i++) {
|
||||
component[i].resetAll();
|
||||
for (int j = 0; j < MAX_COMPONENT_ASSETS; j++) {
|
||||
@@ -469,8 +485,10 @@ void AppData::storeAllSettings()
|
||||
storeAll();
|
||||
for (int i = 0; i < MAX_PROFILES; i++)
|
||||
profile[i].storeAll();
|
||||
for (int i = 0; i < MAX_JOYSTICKS; i++)
|
||||
for (int i = 0; i < MAX_JS_AXES; i++)
|
||||
joystick[i].storeAll();
|
||||
for (int i = 0; i < MAX_JS_BUTTONS; i++)
|
||||
jsButton[i].storeAll();
|
||||
for (int i = 0; i < MAX_COMPONENTS; i++) {
|
||||
component[i].storeAll();
|
||||
for (int j = 0; j < MAX_COMPONENT_ASSETS; j++)
|
||||
|
||||
@@ -59,7 +59,8 @@
|
||||
#define CPN_SETTINGS_INI_PATH QString(CPN_SETTINGS_BACKUP_DIR % "/" % CPN_SETTINGS_INI_FILE)
|
||||
|
||||
#define MAX_PROFILES 20
|
||||
#define MAX_JOYSTICKS 8
|
||||
#define MAX_JS_AXES 10
|
||||
#define MAX_JS_BUTTONS 32
|
||||
#define MAX_COMPONENTS 10
|
||||
#define MAX_COMPONENT_ASSETS 5
|
||||
|
||||
@@ -347,6 +348,26 @@ class JStickData: public CompStoreObj
|
||||
int index;
|
||||
};
|
||||
|
||||
class JButtonData: public CompStoreObj
|
||||
{
|
||||
Q_OBJECT
|
||||
public slots:
|
||||
bool existsOnDisk();
|
||||
|
||||
protected:
|
||||
explicit JButtonData();
|
||||
void setIndex(int idx) { index = idx; }
|
||||
inline QString propertyGroup() const override { return QStringLiteral("JsButton"); }
|
||||
inline QString settingsPath() const override { return QString("%1/%2/").arg(propertyGroup()).arg(index); }
|
||||
friend class AppData;
|
||||
|
||||
private:
|
||||
PROPERTY(int, button_idx, -1)
|
||||
PROPERTY(int, button_inv, 0)
|
||||
|
||||
int index;
|
||||
};
|
||||
|
||||
|
||||
//! \brief Profile class stores properties related to each Radio Profile.
|
||||
//! \todo TODO: Remove or refactor stored radio settings system (#4583)
|
||||
@@ -592,7 +613,8 @@ class AppData: public CompStoreObj
|
||||
bool exportSettingsToFile(const QString & expFile, QString & resultMsg);
|
||||
|
||||
Profile profile[MAX_PROFILES];
|
||||
JStickData joystick[MAX_JOYSTICKS];
|
||||
JStickData joystick[MAX_JS_AXES];
|
||||
JButtonData jsButton[MAX_JS_BUTTONS];
|
||||
FwRevision fwRev;
|
||||
ComponentData component[MAX_COMPONENTS];
|
||||
|
||||
|
||||
@@ -61,6 +61,12 @@ option(HARDWARE_TRAINER_MULTI "Allow multi trainer" OFF)
|
||||
option(BOOTLOADER "Include Bootloader" ON)
|
||||
option(FWDRIVE "Attach also firmware drive with USB" OFF)
|
||||
|
||||
if(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)
|
||||
option(USBJ_EX "Enable USB Joystick Extension" OFF)
|
||||
else()
|
||||
option(USBJ_EX "Enable USB Joystick Extension" ON)
|
||||
endif()
|
||||
|
||||
# since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags.
|
||||
set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).")
|
||||
set(FIRMWARE_C_FLAGS_DEBUG "-g" CACHE STRING "Additional flags for firmware target (Debug config) c compiler (note: CMAKE_C_FLAGS_DEBUG is ignored for firmware/bootloader).")
|
||||
@@ -418,6 +424,14 @@ if(GUI)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
if(USBJ_EX)
|
||||
add_definitions(-DUSBJ_EX)
|
||||
set(SRC
|
||||
${SRC}
|
||||
usb_joystick.cpp
|
||||
)
|
||||
endif()
|
||||
foreach(FILE ${TARGET_SRC})
|
||||
set(SRC targets/${TARGET_DIR}/${FILE} ${SRC})
|
||||
endforeach()
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
+10
-10
@@ -118,36 +118,36 @@ static inline void check_struct()
|
||||
|
||||
#if defined(PCBXLITES)
|
||||
CHKSIZE(RadioData, 862);
|
||||
CHKSIZE(ModelData, 6164);
|
||||
CHKSIZE(ModelData, 6217);
|
||||
#elif defined(PCBXLITE)
|
||||
CHKSIZE(RadioData, 860);
|
||||
CHKSIZE(ModelData, 6164);
|
||||
CHKSIZE(ModelData, 6217);
|
||||
#elif defined(RADIO_TPRO)
|
||||
CHKSIZE(RadioData, 843);
|
||||
CHKSIZE(ModelData, 6189);
|
||||
CHKSIZE(ModelData, 6242);
|
||||
#elif defined(RADIO_BOXER)
|
||||
CHKSIZE(RadioData, 875);
|
||||
CHKSIZE(ModelData, 6165);
|
||||
CHKSIZE(ModelData, 6218);
|
||||
#elif defined(PCBX7)
|
||||
CHKSIZE(RadioData, 866);
|
||||
CHKSIZE(ModelData, 6164);
|
||||
CHKSIZE(ModelData, 6217);
|
||||
#elif defined(PCBX9E)
|
||||
CHKSIZE(RadioData, 956);
|
||||
CHKSIZE(ModelData, 6616);
|
||||
CHKSIZE(ModelData, 6669);
|
||||
#elif defined(PCBX9D) || defined(PCBX9DP)
|
||||
CHKSIZE(RadioData, 898);
|
||||
CHKSIZE(ModelData, 6608);
|
||||
CHKSIZE(ModelData, 6661);
|
||||
#elif defined(PCBHORUS)
|
||||
#if defined(PCBX10)
|
||||
CHKSIZE(RadioData, 924);
|
||||
CHKSIZE(ModelData, 15378);
|
||||
CHKSIZE(ModelData, 15431);
|
||||
#else
|
||||
CHKSIZE(RadioData, 906);
|
||||
CHKSIZE(ModelData, 15376);
|
||||
CHKSIZE(ModelData, 15429);
|
||||
#endif
|
||||
#elif defined(PCBNV14)
|
||||
CHKSIZE(RadioData, 852);
|
||||
CHKSIZE(ModelData, 15192);
|
||||
CHKSIZE(ModelData, 15245);
|
||||
#endif
|
||||
|
||||
#undef CHKSIZE
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "opentx_types.h"
|
||||
#include "globals.h"
|
||||
#include "serial.h"
|
||||
#include "usb_joystick.h"
|
||||
|
||||
#if defined(PCBTARANIS)
|
||||
#define N_TARANIS_FIELD(x)
|
||||
@@ -624,6 +625,36 @@ PACK(struct PartialModel {
|
||||
TimerData timers[MAX_TIMERS];
|
||||
});
|
||||
|
||||
/*
|
||||
* USB Joystick channel structure
|
||||
*/
|
||||
|
||||
PACK(struct USBJoystickChData {
|
||||
uint8_t mode:3 ENUM(USBJoystickCh);
|
||||
uint8_t inversion:1;
|
||||
uint8_t param:4;
|
||||
uint8_t btn_num:5;
|
||||
uint8_t switch_npos:3;
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
NOBACKUP(
|
||||
uint8_t lastBtnNumNoCLip() {
|
||||
uint8_t last = btn_num + switch_npos;
|
||||
// Use one less joystick button for 2POS and 3POS switches for Companion mode
|
||||
if ((param == USBJOYS_BTN_MODE_COMPANION) && (switch_npos > 0) && (switch_npos < 3)) last -= 1;
|
||||
return last;
|
||||
}
|
||||
uint8_t lastBtnNum() {
|
||||
uint8_t last = lastBtnNumNoCLip();
|
||||
if (last >= USBJ_BUTTON_SIZE) {
|
||||
last = USBJ_BUTTON_SIZE - 1;
|
||||
}
|
||||
return last;
|
||||
}
|
||||
);
|
||||
#endif
|
||||
});
|
||||
|
||||
PACK(struct ModelData {
|
||||
CUST_ATTR(semver,nullptr,w_semver);
|
||||
ModelHeader header;
|
||||
@@ -725,6 +756,11 @@ PACK(struct ModelData {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t usbJoystickExtMode:1;
|
||||
uint8_t usbJoystickIfMode:3 ENUM(USBJoystickIfMode);
|
||||
uint8_t usbJoystickCircularCut:4;
|
||||
USBJoystickChData usbJoystickCh[USBJ_MAX_JOYSTICK_CHANNELS];
|
||||
});
|
||||
|
||||
/*
|
||||
|
||||
@@ -131,6 +131,9 @@ void menuModelSensor(event_t event);
|
||||
void menuModelDisplay(event_t event);
|
||||
void menuModelTemplates(event_t event);
|
||||
void menuModelGVarOne(event_t event);
|
||||
#if defined(USBJ_EX)
|
||||
void menuModelUSBJoystick(event_t event);
|
||||
#endif
|
||||
|
||||
static const MenuHandlerFunc menuTabModel[] = {
|
||||
menuModelSelect,
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "opentx.h"
|
||||
#include "mixer_scheduler.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
#endif
|
||||
|
||||
#if !defined(EEPROM)
|
||||
#include "storage/sdcard_common.h"
|
||||
#include "storage/modelslist.h"
|
||||
@@ -193,6 +197,15 @@ enum MenuModelSetupItems {
|
||||
ITEM_MODEL_SETUP_TRAINER_CHANNELS,
|
||||
ITEM_MODEL_SETUP_TRAINER_PPM_PARAMS,
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_LABEL,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_MODE,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_IF_MODE,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_CIRC_CUTOUT,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_CH_BUTTON,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_APPLY,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_LINES_COUNT
|
||||
};
|
||||
|
||||
@@ -443,6 +456,25 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event)
|
||||
NUM_SWITCHES - 1, /* Switch warning */
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
inline uint8_t USB_JOYSTICK_EXTROW()
|
||||
{
|
||||
return (usbJoystickExtMode() ? (uint8_t)0 : HIDDEN_ROW);
|
||||
}
|
||||
|
||||
inline uint8_t USB_JOYSTICK_APPLYROW()
|
||||
{
|
||||
if(!usbJoystickExtMode()) return HIDDEN_ROW;
|
||||
if(usbJoystickSettingsChanged()) return (uint8_t)0;
|
||||
return READONLY_ROW;
|
||||
}
|
||||
|
||||
#define USB_JOYSTICK_ROWS LABEL(USBJoystick), (uint8_t)0, USB_JOYSTICK_EXTROW(), \
|
||||
USB_JOYSTICK_EXTROW(), USB_JOYSTICK_EXTROW(), USB_JOYSTICK_APPLYROW()
|
||||
#else
|
||||
#define USB_JOYSTICK_ROWS
|
||||
#endif
|
||||
|
||||
#if defined(FUNCTION_SWITCHES)
|
||||
static const char* _fct_sw_start[] = { STR_CHAR_UP, STR_CHAR_DOWN, "=" };
|
||||
#endif
|
||||
@@ -491,7 +523,9 @@ void menuModelSetup(event_t event)
|
||||
|
||||
EXTRA_MODULE_ROWS
|
||||
|
||||
TRAINER_ROWS
|
||||
TRAINER_ROWS,
|
||||
|
||||
USB_JOYSTICK_ROWS
|
||||
});
|
||||
|
||||
MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, HEADER_LINE + ITEM_MODEL_SETUP_LINES_COUNT);
|
||||
@@ -2053,6 +2087,39 @@ void menuModelSetup(event_t event)
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_LABEL:
|
||||
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_LABEL);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_MODE:
|
||||
g_model.usbJoystickExtMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_USBJOYSTICK_EXTMODE, STR_VUSBJOYSTICK_EXTMODE, g_model.usbJoystickExtMode, 0, 1, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_IF_MODE:
|
||||
g_model.usbJoystickIfMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_USBJOYSTICK_IF_MODE, STR_VUSBJOYSTICK_IF_MODE, g_model.usbJoystickIfMode, 0, USBJOYS_LAST, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_CIRC_CUTOUT:
|
||||
g_model.usbJoystickCircularCut = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_USBJOYSTICK_CIRC_COUTOUT, STR_VUSBJOYSTICK_CIRC_COUTOUT, g_model.usbJoystickCircularCut, 0, 2, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_CH_BUTTON:
|
||||
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_USBJOYSTICK_SETTINGS), attr);
|
||||
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
pushMenu(menuModelUSBJoystick);
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_APPLY:
|
||||
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_USBJOYSTICK_APPLY_CHANGES), attr);
|
||||
if (attr && !READ_ONLY() && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
onUSBJoystickModelChanged();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,9 @@ void menuModelCustomScripts(event_t event);
|
||||
void menuModelTelemetry(event_t event);
|
||||
void menuModelSensor(event_t event);
|
||||
void menuModelDisplay(event_t event);
|
||||
#if defined(USBJ_EX)
|
||||
void menuModelUSBJoystick(event_t event);
|
||||
#endif
|
||||
|
||||
extern const MenuHandlerFunc menuTabModel[MENU_MODEL_PAGES_COUNT];
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "opentx.h"
|
||||
#include "mixer_scheduler.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
#endif
|
||||
|
||||
#if defined(CROSSFIRE)
|
||||
#include "telemetry/crossfire.h"
|
||||
#endif
|
||||
@@ -153,6 +157,15 @@ enum MenuModelSetupItems {
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_TRAINER_CHANNELS,
|
||||
ITEM_MODEL_SETUP_TRAINER_PPM_PARAMS,
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_LABEL,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_MODE,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_IF_MODE,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_CIRC_CUTOUT,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_CH_BUTTON,
|
||||
ITEM_MODEL_SETUP_USBJOYSTICK_APPLY,
|
||||
#endif
|
||||
ITEM_MODEL_SETUP_LINES_COUNT
|
||||
};
|
||||
|
||||
@@ -392,6 +405,25 @@ void onBluetoothConnectMenu(const char * result)
|
||||
#include "common/stdlcd/model_setup_afhds3.cpp"
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
inline uint8_t USB_JOYSTICK_EXTROW()
|
||||
{
|
||||
return (usbJoystickExtMode() ? (uint8_t)0 : HIDDEN_ROW);
|
||||
}
|
||||
|
||||
inline uint8_t USB_JOYSTICK_APPLYROW()
|
||||
{
|
||||
if(!usbJoystickExtMode()) return HIDDEN_ROW;
|
||||
if(usbJoystickSettingsChanged()) return (uint8_t)0;
|
||||
return READONLY_ROW;
|
||||
}
|
||||
|
||||
#define USB_JOYSTICK_ROWS LABEL(USBJoystick), (uint8_t)0, USB_JOYSTICK_EXTROW(), \
|
||||
USB_JOYSTICK_EXTROW(), USB_JOYSTICK_EXTROW(), USB_JOYSTICK_APPLYROW()
|
||||
#else
|
||||
#define USB_JOYSTICK_ROWS
|
||||
#endif
|
||||
|
||||
void menuModelSetup(event_t event)
|
||||
{
|
||||
horzpos_t l_posHorz = menuHorizontalPosition;
|
||||
@@ -470,7 +502,9 @@ void menuModelSetup(event_t event)
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2
|
||||
IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3
|
||||
|
||||
TRAINER_ROWS
|
||||
TRAINER_ROWS,
|
||||
|
||||
USB_JOYSTICK_ROWS
|
||||
});
|
||||
|
||||
MENU_CHECK(menuTabModel, MENU_MODEL_SETUP, ITEM_MODEL_SETUP_LINES_COUNT);
|
||||
@@ -1768,6 +1802,39 @@ void menuModelSetup(event_t event)
|
||||
modelSetupModulePxx2ReceiverLine(CURRENT_MODULE_EDITED(k), CURRENT_RECEIVER_EDITED(k), y, event, attr);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_LABEL:
|
||||
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_LABEL);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_MODE:
|
||||
g_model.usbJoystickExtMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_USBJOYSTICK_EXTMODE, STR_VUSBJOYSTICK_EXTMODE, g_model.usbJoystickExtMode, 0, 1, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_IF_MODE:
|
||||
g_model.usbJoystickIfMode = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_USBJOYSTICK_IF_MODE, STR_VUSBJOYSTICK_IF_MODE, g_model.usbJoystickIfMode, 0, USBJOYS_LAST, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_CIRC_CUTOUT:
|
||||
g_model.usbJoystickCircularCut = editChoice(MODEL_SETUP_2ND_COLUMN, y, INDENT TR_USBJOYSTICK_CIRC_COUTOUT, STR_VUSBJOYSTICK_CIRC_COUTOUT, g_model.usbJoystickCircularCut, 0, 2, attr, event);
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_CH_BUTTON:
|
||||
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_USBJOYSTICK_SETTINGS), attr);
|
||||
if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
pushMenu(menuModelUSBJoystick);
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_MODEL_SETUP_USBJOYSTICK_APPLY:
|
||||
lcdDrawText(INDENT_WIDTH, y, BUTTON(TR_USBJOYSTICK_APPLY_CHANGES), attr);
|
||||
if (attr && !READ_ONLY() && event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
onUSBJoystickModelChanged();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -222,3 +222,8 @@ add_gui_src(lvgl_widgets/input_mix_group.c)
|
||||
if(HARDWARE_TOUCH)
|
||||
add_gui_src(keyboard_curve.cpp)
|
||||
endif()
|
||||
|
||||
if(USBJ_EX)
|
||||
add_gui_src(model_usbjoystick.cpp)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -83,6 +83,9 @@ static const uint8_t mask_model_special_functions[] = {
|
||||
static const uint8_t mask_model_telemetry[] = {
|
||||
#include "mask_model_telemetry.lbm"
|
||||
};
|
||||
static const uint8_t mask_model_usb[] = {
|
||||
#include "mask_model_usb.lbm"
|
||||
};
|
||||
static const uint8_t mask_menu_model_select[] = {
|
||||
#include "mask_menu_model_select.lbm" //TODO: someone may want to make proper icon
|
||||
};
|
||||
@@ -343,6 +346,7 @@ static const _BuiltinIcon _builtinIcons[] = {
|
||||
{ICON_MODEL_SPECIAL_FUNCTIONS, mask_model_special_functions},
|
||||
{ICON_MODEL_LUA_SCRIPTS, mask_model_lua_scripts},
|
||||
{ICON_MODEL_TELEMETRY, mask_model_telemetry},
|
||||
{ICON_MODEL_USB, mask_model_usb},
|
||||
{ICON_MODEL_SELECT, mask_menu_model_select},
|
||||
{ICON_MODEL_SELECT_CATEGORY, mask_model_select_category},
|
||||
{ICON_THEME, mask_menu_theme},
|
||||
|
||||
@@ -56,6 +56,7 @@ enum MenuIcons {
|
||||
ICON_MODEL_SPECIAL_FUNCTIONS,
|
||||
ICON_MODEL_LUA_SCRIPTS,
|
||||
ICON_MODEL_TELEMETRY,
|
||||
ICON_MODEL_USB,
|
||||
ICON_MODEL_SELECT,
|
||||
ICON_MODEL_SELECT_CATEGORY,
|
||||
ICON_THEME,
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
#include "throttle_params.h"
|
||||
#include "preflight_checks.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "model_usbjoystick.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
@@ -329,6 +333,15 @@ void ModelSetupPage::build(FormWindow * window)
|
||||
|
||||
btn = new SubScreenButton(form, STR_THROTTLE_LABEL, []() { new ThrottleParams(); });
|
||||
lv_obj_set_grid_cell(btn->getLvObj(), LV_GRID_ALIGN_STRETCH, 2, 1, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
form = new FormGroup(oform, rect_t{});
|
||||
form->setFlexLayout(LV_FLEX_FLOW_ROW, lv_dpx(PAGE_PADDING));
|
||||
lv_obj_set_grid_dsc_array(form->getLvObj(), col_dsc, row_dsc);
|
||||
|
||||
btn = new SubScreenButton(form, STR_USBJOYSTICK_LABEL, []() { new ModelUSBJoystickPage(); });
|
||||
lv_obj_set_grid_cell(btn->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, 1, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MAX_SUBSCREEN_BTNS 9
|
||||
|
||||
@@ -0,0 +1,601 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "model_usbjoystick.h"
|
||||
#include "usb_joystick.h"
|
||||
#include "channel_bar.h"
|
||||
#include "button_matrix.h"
|
||||
#include "lvgl_widgets/input_mix_line.h"
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
#if LCD_W > LCD_H // Landscape
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_EDIT_STATUS_BAR_WIDTH 250
|
||||
#define USBCH_EDIT_STATUS_BAR_MARGIN 3
|
||||
#define USBCH_EDIT_RIGHT_MARGIN 0
|
||||
#define USBCH_COLS 4
|
||||
|
||||
static const lv_coord_t ch_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_FR(1), LV_GRID_FR(2),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_CHN_ROWS 1
|
||||
#define USBCH_BTN_MODE_COL 4
|
||||
#define USBCH_BTN_MODE_ROW 0
|
||||
#define USBCH_LINE_HEIGHT PAGE_LINE_HEIGHT + 14
|
||||
|
||||
static const lv_coord_t b_col_dsc[] = {LV_GRID_FR(10), 20, LV_GRID_FR(10), LV_GRID_FR(12),
|
||||
LV_GRID_FR(9), LV_GRID_FR(9), LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t b_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#else // Portrait
|
||||
|
||||
static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_EDIT_STATUS_BAR_WIDTH 160
|
||||
#define USBCH_EDIT_STATUS_BAR_MARGIN 0
|
||||
#define USBCH_EDIT_RIGHT_MARGIN 3
|
||||
#define USBCH_COLS 2
|
||||
|
||||
static const lv_coord_t ch_col_dsc[] = {LV_GRID_FR(2), LV_GRID_FR(3),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#define USBCH_CHN_ROWS 2
|
||||
#define USBCH_BTN_MODE_COL 2
|
||||
#define USBCH_BTN_MODE_ROW 1
|
||||
#define USBCH_LINE_HEIGHT 2 * PAGE_LINE_HEIGHT + 10
|
||||
|
||||
static const lv_coord_t b_col_dsc[] = {LV_GRID_FR(1), 20, LV_GRID_FR(1), LV_GRID_FR(1),
|
||||
LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
static const lv_coord_t b_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
#endif
|
||||
|
||||
#define USBCH_BTNMX_COL 8
|
||||
|
||||
static const lv_coord_t row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST};
|
||||
|
||||
class USBChannelEditStatusBar : public Window
|
||||
{
|
||||
public:
|
||||
USBChannelEditStatusBar(Window *parent, const rect_t &rect, int8_t channel) :
|
||||
Window(parent, rect), _channel(channel)
|
||||
{
|
||||
channelBar = new ComboChannelBar(this, {USBCH_EDIT_STATUS_BAR_MARGIN, 0, rect.w - (USBCH_EDIT_STATUS_BAR_MARGIN * 2), rect.h}, channel);
|
||||
channelBar->setLeftMargin(0);
|
||||
channelBar->setTextColor(COLOR_THEME_PRIMARY2);
|
||||
channelBar->setOutputChannelBarLimitColor(COLOR_THEME_EDIT);
|
||||
}
|
||||
|
||||
protected:
|
||||
ComboChannelBar *channelBar;
|
||||
int8_t _channel;
|
||||
};
|
||||
|
||||
static void btnsel_event_cb(lv_event_t* e);
|
||||
|
||||
class USBChannelButtonSel : public ButtonMatrix
|
||||
{
|
||||
public:
|
||||
USBChannelButtonSel(Window* parent, const rect_t& rect, uint8_t channel,
|
||||
std::function<void(int)> _setValue) :
|
||||
ButtonMatrix(parent, rect),
|
||||
m_channel(channel),
|
||||
m_setValue(std::move(_setValue))
|
||||
{
|
||||
initBtnMap(USBCH_BTNMX_COL, USBJ_BUTTON_SIZE);
|
||||
char snum[5];
|
||||
for (uint8_t btn = 0; btn < USBJ_BUTTON_SIZE; btn++) {
|
||||
snprintf(snum, 5, "%u", btn);
|
||||
setText(btn, snum);
|
||||
}
|
||||
update();
|
||||
|
||||
lv_obj_add_event_cb(lvobj, btnsel_event_cb, LV_EVENT_DRAW_PART_BEGIN, this);
|
||||
|
||||
memset(m_btns, 0, USBJ_BUTTON_SIZE);
|
||||
for (uint8_t ch = 0; ch < USBJ_MAX_JOYSTICK_CHANNELS; ch++) {
|
||||
if (ch != m_channel) {
|
||||
USBJoystickChData * cch = usbJChAddress(ch);
|
||||
|
||||
if (cch->mode == USBJOYS_CH_BUTTON) {
|
||||
uint8_t last = cch->lastBtnNum();
|
||||
for(uint8_t b = cch->btn_num; b <= last; b++) {
|
||||
m_btns[b] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
updateState();
|
||||
}
|
||||
|
||||
void setValue(int val)
|
||||
{
|
||||
if (m_setValue) {
|
||||
m_setValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
void onPress(uint8_t btn_id) override
|
||||
{
|
||||
setValue(btn_id);
|
||||
updateState();
|
||||
}
|
||||
|
||||
bool isActive(uint8_t btn_id) override { return false; }
|
||||
|
||||
uint8_t getBtnState(uint8_t id)
|
||||
{
|
||||
if (id < USBJ_BUTTON_SIZE) return m_btns[id];
|
||||
return 0;
|
||||
}
|
||||
|
||||
void updateState()
|
||||
{
|
||||
USBJoystickChData * cch = usbJChAddress(m_channel);
|
||||
|
||||
for(uint8_t i = 0; i < USBJ_BUTTON_SIZE; i++) m_btns[i] &= 1;
|
||||
uint8_t last = cch->lastBtnNum();
|
||||
for(uint8_t b = cch->btn_num; b <= last; b++) m_btns[b] |= 2;
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t m_channel = 0;
|
||||
std::function<void(int)> m_setValue;
|
||||
uint8_t m_btns[USBJ_BUTTON_SIZE];
|
||||
};
|
||||
|
||||
static void btnsel_event_cb(lv_event_t* e)
|
||||
{
|
||||
lv_event_code_t code = lv_event_get_code(e);
|
||||
|
||||
if (code == LV_EVENT_DRAW_PART_BEGIN) {
|
||||
lv_obj_draw_part_dsc_t* dsc = lv_event_get_draw_part_dsc(e);
|
||||
|
||||
if(dsc->class_p == &lv_btnmatrix_class && dsc->type == LV_BTNMATRIX_DRAW_PART_BTN) {
|
||||
dsc->rect_dsc->radius = LV_RADIUS_CIRCLE;
|
||||
auto btsel = (USBChannelButtonSel*)lv_event_get_user_data(e);
|
||||
|
||||
uint8_t state = btsel->getBtnState((uint8_t)dsc->id);
|
||||
if (state == 1) {
|
||||
dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_DISABLED);
|
||||
dsc->label_dsc->color = makeLvColor(COLOR_THEME_PRIMARY1);
|
||||
}
|
||||
else if (state == 2) {
|
||||
dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_EDIT);
|
||||
dsc->label_dsc->color = makeLvColor(COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
else if (state == 3) {
|
||||
dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_WARNING);
|
||||
dsc->label_dsc->color = makeLvColor(COLOR_THEME_PRIMARY2);
|
||||
}
|
||||
else {
|
||||
dsc->rect_dsc->bg_color = makeLvColor(COLOR_THEME_PRIMARY2);
|
||||
dsc->label_dsc->color = makeLvColor(COLOR_THEME_SECONDARY1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define USBCH_LINES 3
|
||||
#define SET_VALUE_WUPDATE(value) [=](int32_t newValue) { value = newValue; SET_DIRTY(); this->update(); }
|
||||
|
||||
class USBChannelEditWindow : public Page
|
||||
{
|
||||
public:
|
||||
USBChannelEditWindow(uint8_t channel) :
|
||||
Page(ICON_MODEL_USB), channel(channel)
|
||||
{
|
||||
auto form = new FormWindow(&body, rect_t{});
|
||||
form->padAll(4);
|
||||
form->padLeft(8);
|
||||
form->padRight(8);
|
||||
|
||||
buildHeader(&header);
|
||||
buildBody(form);
|
||||
}
|
||||
|
||||
protected:
|
||||
uint8_t channel;
|
||||
USBChannelEditStatusBar* statusBar = nullptr;
|
||||
FormWindow* m_btnModeFrame = nullptr;
|
||||
Window* m_axisModeLine = nullptr;
|
||||
Window* m_simModeLine = nullptr;
|
||||
USBChannelButtonSel* _BtnNumSel = nullptr;
|
||||
StaticText* collisionText = nullptr;
|
||||
Choice* m_btnPosChoice = nullptr;
|
||||
|
||||
protected:
|
||||
void update()
|
||||
{
|
||||
USBJoystickChData * cch = usbJChAddress(channel);
|
||||
|
||||
lv_obj_add_flag(m_btnModeFrame->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_add_flag(m_axisModeLine->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
lv_obj_add_flag(m_simModeLine->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
if (cch->mode == USBJOYS_CH_BUTTON)
|
||||
lv_obj_clear_flag(m_btnModeFrame->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
else if (cch->mode == USBJOYS_CH_AXIS)
|
||||
lv_obj_clear_flag(m_axisModeLine->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
else if (cch->mode == USBJOYS_CH_SIM)
|
||||
lv_obj_clear_flag(m_simModeLine->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
if(m_btnPosChoice)
|
||||
m_btnPosChoice->enable((cch->param != USBJOYS_BTN_MODE_SW_EMU) && (cch->param != USBJOYS_BTN_MODE_DELTA));
|
||||
|
||||
if(collisionText) {
|
||||
collisionText->setText("");
|
||||
lv_obj_add_flag(collisionText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
if (cch->mode == USBJOYS_CH_BUTTON) {
|
||||
if (isUSBBtnNumCollision(channel)) {
|
||||
collisionText->setText(STR_USBJOYSTICK_BTN_COLLISION);
|
||||
lv_obj_clear_flag(collisionText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_AXIS) {
|
||||
if (isUSBAxisCollision(channel)) {
|
||||
collisionText->setText(STR_USBJOYSTICK_AXIS_COLLISION);
|
||||
lv_obj_clear_flag(collisionText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_SIM) {
|
||||
if (isUSBSimCollision(channel)) {
|
||||
collisionText->setText(STR_USBJOYSTICK_AXIS_COLLISION);
|
||||
lv_obj_clear_flag(collisionText->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_BtnNumSel->updateState();
|
||||
}
|
||||
|
||||
void buildHeader(Window *window)
|
||||
{
|
||||
header.setTitle(STR_USBJOYSTICK_LABEL);
|
||||
header.setTitle2(getSourceString(MIXSRC_CH1 + channel));
|
||||
|
||||
statusBar = new USBChannelEditStatusBar(
|
||||
window,
|
||||
{window->getRect().w - USBCH_EDIT_STATUS_BAR_WIDTH - USBCH_EDIT_RIGHT_MARGIN,
|
||||
0, USBCH_EDIT_STATUS_BAR_WIDTH, MENU_HEADER_HEIGHT + 3},
|
||||
channel);
|
||||
}
|
||||
|
||||
void buildBody(FormWindow* form)
|
||||
{
|
||||
FlexGridLayout grid(ch_col_dsc, row_dsc, 2);
|
||||
form->setFlexLayout();
|
||||
|
||||
USBJoystickChData * cch = usbJChAddress(channel);
|
||||
|
||||
auto line = form->newLine(&grid);
|
||||
|
||||
line->padTop(0);
|
||||
line->padBottom(0);
|
||||
collisionText = new StaticText(line, rect_t{}, "", OPAQUE, FONT(BOLD) | COLOR_THEME_PRIMARY2 | CENTERED);
|
||||
collisionText->setBackgroundColor(COLOR_THEME_WARNING);
|
||||
lv_obj_set_grid_cell(collisionText->getLvObj(), LV_GRID_ALIGN_STRETCH, 0, USBCH_COLS, LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_CH_MODE, 0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(line, rect_t{}, STR_VUSBJOYSTICK_CH_MODE, 0, USBJOYS_CH_LAST,
|
||||
GET_DEFAULT(cch->mode), SET_VALUE_WUPDATE(cch->mode));
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
line = form->newLine(&grid);
|
||||
#endif
|
||||
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_CH_INVERSION, 0, COLOR_THEME_PRIMARY1);
|
||||
new CheckBox(line, rect_t{}, GET_SET_DEFAULT(cch->inversion));
|
||||
|
||||
line = form->newLine(&grid);
|
||||
m_btnModeFrame = new FormWindow(line, rect_t{});
|
||||
m_btnModeFrame->setFlexLayout();
|
||||
|
||||
line = m_btnModeFrame->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_CH_BTNMODE, 0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(line, rect_t{}, STR_VUSBJOYSTICK_CH_BTNMODE, 0, USBJOYS_BTN_MODE_LAST,
|
||||
GET_DEFAULT(cch->param),
|
||||
[=](int32_t newValue)
|
||||
{
|
||||
cch->param = newValue;
|
||||
if(cch->param == USBJOYS_BTN_MODE_SW_EMU) m_btnPosChoice->setValue(0);
|
||||
else if(cch->param == USBJOYS_BTN_MODE_DELTA) m_btnPosChoice->setValue(1);
|
||||
SET_DIRTY();
|
||||
this->update();
|
||||
});
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
line = m_btnModeFrame->newLine(&grid);
|
||||
#endif
|
||||
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_CH_SWPOS, 0, COLOR_THEME_PRIMARY1);
|
||||
m_btnPosChoice = new Choice(line, rect_t{}, STR_VUSBJOYSTICK_CH_SWPOS, 0, 7,
|
||||
GET_DEFAULT(cch->switch_npos), SET_VALUE_WUPDATE(cch->switch_npos));
|
||||
|
||||
line = m_btnModeFrame->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_CH_BTNNUM, 0, COLOR_THEME_PRIMARY1);
|
||||
#if LCD_H > LCD_W
|
||||
line = m_btnModeFrame->newLine(&grid);
|
||||
#endif
|
||||
_BtnNumSel = new USBChannelButtonSel(line, rect_t{},
|
||||
channel, SET_VALUE_WUPDATE(cch->btn_num));
|
||||
|
||||
m_axisModeLine = form->newLine(&grid);
|
||||
new StaticText(m_axisModeLine, rect_t{}, STR_USBJOYSTICK_CH_AXIS, 0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(m_axisModeLine, rect_t{}, STR_VUSBJOYSTICK_CH_AXIS, 0, USBJOYS_AXIS_LAST,
|
||||
GET_DEFAULT(cch->param), SET_VALUE_WUPDATE(cch->param));
|
||||
|
||||
m_simModeLine = form->newLine(&grid);
|
||||
new StaticText(m_simModeLine, rect_t{}, STR_USBJOYSTICK_CH_SIM, 0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(m_simModeLine, rect_t{}, STR_VUSBJOYSTICK_CH_SIM, 0, USBJOYS_SIM_LAST,
|
||||
GET_DEFAULT(cch->param), SET_VALUE_WUPDATE(cch->param));
|
||||
|
||||
update();
|
||||
}
|
||||
};
|
||||
|
||||
class USBChannelLineButton : public Button
|
||||
{
|
||||
public:
|
||||
USBChannelLineButton(Window* parent, uint8_t index) :
|
||||
Button(parent, rect_t{}, nullptr, 0, 0, input_mix_line_create), index(index)
|
||||
{
|
||||
setHeight(USBCH_LINE_HEIGHT);
|
||||
|
||||
lv_obj_set_layout(lvobj, LV_LAYOUT_GRID);
|
||||
lv_obj_set_grid_dsc_array(lvobj, b_col_dsc, b_row_dsc);
|
||||
lv_obj_set_style_pad_row(lvobj, 0, 0);
|
||||
lv_obj_set_style_pad_column(lvobj, 4, 0);
|
||||
|
||||
lv_obj_add_event_cb(lvobj, USBChannelLineButton::on_draw,
|
||||
LV_EVENT_DRAW_MAIN_BEGIN, nullptr);
|
||||
}
|
||||
|
||||
static void on_draw(lv_event_t* e)
|
||||
{
|
||||
lv_obj_t* target = lv_event_get_target(e);
|
||||
auto line = (USBChannelLineButton*)lv_obj_get_user_data(target);
|
||||
if (line) {
|
||||
if (!line->init)
|
||||
line->delayed_init(e);
|
||||
else
|
||||
line->refresh();
|
||||
}
|
||||
}
|
||||
|
||||
void delayed_init(lv_event_t* e)
|
||||
{
|
||||
m_chn = lv_label_create(lvobj);
|
||||
lv_obj_set_grid_cell(m_chn, LV_GRID_ALIGN_START, 0, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, USBCH_CHN_ROWS);
|
||||
|
||||
m_inverse = new StaticBitmap(this, rect_t{0, 0, 11, 16}, chanMonInvertedBitmap, COLOR_THEME_SECONDARY1, false);
|
||||
lv_obj_set_grid_cell(m_inverse->getLvObj(), LV_GRID_ALIGN_START, 1, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
m_mode = lv_label_create(lvobj);
|
||||
lv_obj_set_grid_cell(m_mode, LV_GRID_ALIGN_START, 2, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
m_param = lv_label_create(lvobj);
|
||||
lv_obj_set_grid_cell(m_param, LV_GRID_ALIGN_START, 3, 1,
|
||||
LV_GRID_ALIGN_CENTER, 0, 1);
|
||||
|
||||
m_btn_mode = lv_label_create(lvobj);
|
||||
lv_obj_set_grid_cell(m_btn_mode, LV_GRID_ALIGN_START, USBCH_BTN_MODE_COL, 1,
|
||||
LV_GRID_ALIGN_CENTER, USBCH_BTN_MODE_ROW, 1);
|
||||
|
||||
m_btns = lv_label_create(lvobj);
|
||||
lv_obj_set_grid_cell(m_btns, LV_GRID_ALIGN_START, USBCH_BTN_MODE_COL+1, 1,
|
||||
LV_GRID_ALIGN_CENTER, USBCH_BTN_MODE_ROW, 1);
|
||||
|
||||
lv_label_set_text(m_chn, getSourceString(MIXSRC_CH1 + index));
|
||||
lv_label_set_text(m_mode, "");
|
||||
lv_label_set_text(m_param, "");
|
||||
lv_label_set_text(m_btn_mode, "");
|
||||
lv_label_set_text(m_btns, "");
|
||||
|
||||
init = true;
|
||||
refresh();
|
||||
lv_obj_update_layout(lvobj);
|
||||
|
||||
if (e) {
|
||||
auto param = lv_event_get_param(e);
|
||||
lv_event_send(lvobj, LV_EVENT_DRAW_MAIN, param);
|
||||
}
|
||||
}
|
||||
|
||||
void refresh()
|
||||
{
|
||||
if (!init) return;
|
||||
|
||||
USBJoystickChData * cch = usbJChAddress(index);
|
||||
|
||||
lv_label_set_text(m_mode, STR_VUSBJOYSTICK_CH_MODE[cch->mode]);
|
||||
|
||||
if (cch->inversion)
|
||||
lv_obj_clear_flag(m_inverse->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
else
|
||||
lv_obj_add_flag(m_inverse->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
|
||||
LcdFlags warn = COLOR_THEME_SECONDARY1;
|
||||
LcdFlags font = FONT(STD);
|
||||
const char* param = "";
|
||||
|
||||
if (cch->mode == USBJOYS_CH_BUTTON) {
|
||||
param = STR_VUSBJOYSTICK_CH_BTNMODE[cch->param];
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_AXIS) {
|
||||
param = STR_VUSBJOYSTICK_CH_AXIS[cch->param];
|
||||
if (isUSBAxisCollision(index)) {
|
||||
warn = COLOR_THEME_WARNING;
|
||||
font = FONT(BOLD);
|
||||
}
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_SIM) {
|
||||
param = STR_VUSBJOYSTICK_CH_SIM[cch->param];
|
||||
if (isUSBSimCollision(index)) {
|
||||
warn = COLOR_THEME_WARNING;
|
||||
font = FONT(BOLD);
|
||||
}
|
||||
}
|
||||
|
||||
lv_label_set_text(m_param, param);
|
||||
lv_obj_set_style_text_color(m_param, makeLvColor(warn), 0);
|
||||
lv_obj_set_style_text_font(m_param, getFont(font), 0);
|
||||
|
||||
if (cch->mode == USBJOYS_CH_BUTTON) {
|
||||
lv_label_set_text(m_btn_mode, STR_VUSBJOYSTICK_CH_SWPOS[cch->switch_npos]);
|
||||
|
||||
char str[20];
|
||||
|
||||
uint8_t last = cch->lastBtnNum();
|
||||
if (last > cch->btn_num)
|
||||
snprintf(str, 20, "%u..%u", cch->btn_num, last);
|
||||
else
|
||||
snprintf(str, 20, "%u", cch->btn_num);
|
||||
lv_label_set_text(m_btns, str);
|
||||
if (isUSBBtnNumCollision(index)) {
|
||||
warn = COLOR_THEME_WARNING;
|
||||
font = FONT(BOLD);
|
||||
}
|
||||
lv_obj_set_style_text_color(m_btns, makeLvColor(warn), 0);
|
||||
lv_obj_set_style_text_font(m_btns, getFont(font), 0);
|
||||
} else {
|
||||
lv_label_set_text(m_btn_mode, "");
|
||||
lv_label_set_text(m_btns, "");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
bool init = false;
|
||||
uint8_t index;
|
||||
|
||||
lv_obj_t* m_chn;
|
||||
lv_obj_t* m_mode;
|
||||
lv_obj_t* m_param;
|
||||
lv_obj_t* m_btn_mode;
|
||||
lv_obj_t* m_btns;
|
||||
StaticBitmap* m_inverse;
|
||||
};
|
||||
|
||||
ModelUSBJoystickPage::ModelUSBJoystickPage() :
|
||||
Page(ICON_MODEL_USB)
|
||||
{
|
||||
header.setTitle(STR_USBJOYSTICK_LABEL);
|
||||
|
||||
auto form = new FormWindow(&body, rect_t{});
|
||||
form->padAll(lv_dpx(8));
|
||||
form->setFlexLayout();
|
||||
FlexGridLayout grid(line_col_dsc, row_dsc, 2);
|
||||
|
||||
// Extended mode
|
||||
auto line = form->newLine(&grid);
|
||||
new StaticText(line, rect_t{}, STR_USBJOYSTICK_EXTMODE, 0, COLOR_THEME_PRIMARY1);
|
||||
new Choice(line, rect_t{}, STR_VUSBJOYSTICK_EXTMODE, 0, 1,
|
||||
GET_DEFAULT(g_model.usbJoystickExtMode), SET_VALUE_WUPDATE(g_model.usbJoystickExtMode));
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
line = form->newLine(&grid);
|
||||
#endif
|
||||
|
||||
_IfModeLabel = new StaticText(line, rect_t{}, STR_USBJOYSTICK_IF_MODE, 0, COLOR_THEME_PRIMARY1);
|
||||
_IfMode = new Choice(line, rect_t{}, STR_VUSBJOYSTICK_IF_MODE, 0, USBJOYS_LAST,
|
||||
GET_DEFAULT(g_model.usbJoystickIfMode), SET_VALUE_WUPDATE(g_model.usbJoystickIfMode));
|
||||
|
||||
line = form->newLine(&grid);
|
||||
|
||||
_CircCoutoutLabel = new StaticText(line, rect_t{}, STR_USBJOYSTICK_CIRC_COUTOUT, 0, COLOR_THEME_PRIMARY1);
|
||||
_CircCoutout = new Choice(line, rect_t{}, STR_VUSBJOYSTICK_CIRC_COUTOUT, 0, USBJOYS_LAST,
|
||||
GET_DEFAULT(g_model.usbJoystickCircularCut), SET_VALUE_WUPDATE(g_model.usbJoystickCircularCut));
|
||||
|
||||
#if LCD_H > LCD_W
|
||||
line = form->newLine(&grid);
|
||||
#endif
|
||||
|
||||
_ApplyBtn = new TextButton(line, rect_t{}, STR_USBJOYSTICK_APPLY_CHANGES,
|
||||
[=]() { onUSBJoystickModelChanged(); this->update(); return 0; });
|
||||
|
||||
auto btngrp = new FormGroup(form, rect_t{});
|
||||
_ChannelsGroup = btngrp;
|
||||
btngrp->setFlexLayout();
|
||||
btngrp->padRow(lv_dpx(4));
|
||||
for (uint8_t ch = 0; ch < USBJ_MAX_JOYSTICK_CHANNELS; ch++) {
|
||||
|
||||
// Channel settings
|
||||
auto btn = new USBChannelLineButton(btngrp, ch);
|
||||
|
||||
USBJoystickChData * cch = usbJChAddress(ch);
|
||||
btn->setPressHandler([=]() -> uint8_t {
|
||||
if (cch->mode == USBJOYS_CH_NONE) {
|
||||
editChannel(ch, btn);
|
||||
}
|
||||
else {
|
||||
Menu *menu = new Menu(parent);
|
||||
menu->addLine(STR_EDIT, [=]() {
|
||||
editChannel(ch, btn);
|
||||
});
|
||||
menu->addLine(STR_CLEAR, [=]() {
|
||||
memset(cch, 0, sizeof(USBJoystickChData));
|
||||
SET_DIRTY();
|
||||
btn->invalidate();
|
||||
});
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ModelUSBJoystickPage::update()
|
||||
{
|
||||
const uint8_t usbj_ctrls = 6;
|
||||
Window* ctrls[usbj_ctrls] = { _IfModeLabel, _IfMode, _CircCoutoutLabel, _CircCoutout, _ApplyBtn, _ChannelsGroup };
|
||||
|
||||
for(uint8_t i = 0; i < usbj_ctrls; i++) {
|
||||
if(usbJoystickExtMode()) {
|
||||
lv_obj_clear_flag(ctrls[i]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
_ApplyBtn->enable(usbJoystickSettingsChanged());
|
||||
}
|
||||
else {
|
||||
lv_obj_add_flag(ctrls[i]->getLvObj(), LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ModelUSBJoystickPage::editChannel(uint8_t channel, USBChannelLineButton* btn)
|
||||
{
|
||||
auto chedit = new USBChannelEditWindow(channel);
|
||||
chedit->setCloseHandler(
|
||||
[=]() { this->update(); });
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "page.h"
|
||||
|
||||
class FormGroup;
|
||||
class USBChannelLineButton;
|
||||
|
||||
class ModelUSBJoystickPage : public Page
|
||||
{
|
||||
public:
|
||||
ModelUSBJoystickPage();
|
||||
|
||||
protected:
|
||||
void update();
|
||||
void editChannel(uint8_t channel, USBChannelLineButton* btn);
|
||||
|
||||
protected:
|
||||
Window* _IfModeLabel;
|
||||
Window* _IfMode;
|
||||
Window* _CircCoutoutLabel;
|
||||
Window* _CircCoutout;
|
||||
TextButton* _ApplyBtn;
|
||||
Window* _ChannelsGroup;
|
||||
};
|
||||
@@ -62,3 +62,11 @@ if(PXX2)
|
||||
../common/stdlcd/model_receiver_options.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(USBJ_EX)
|
||||
set(GUI_SRC
|
||||
${GUI_SRC}
|
||||
../common/stdlcd/model_usbjoystick.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -0,0 +1,255 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "opentx.h"
|
||||
#include "usb_joystick.h"
|
||||
|
||||
#define _STR_MAX(x) "/" #x
|
||||
#define STR_MAX(x) _STR_MAX(x)
|
||||
|
||||
#if LCD_W >= 212
|
||||
#define MODE_POS 5*FW
|
||||
#define SUBMODE_POS MODE_POS+2*FW
|
||||
#define USBJ_ONE_2ND_COLUMN (12*FW)
|
||||
#define BTNMODE_POS SUBMODE_POS+5*FW
|
||||
#define BTNNUM_POS BTNMODE_POS+12*FW
|
||||
#else
|
||||
#define MODE_POS 5*FW
|
||||
#define SUBMODE_POS MODE_POS+2*FW
|
||||
#define USBJ_ONE_2ND_COLUMN (12*FW)
|
||||
#define BTNMODE_POS SUBMODE_POS+5*FW
|
||||
#define BTNNUM_POS LCD_W
|
||||
#endif
|
||||
|
||||
enum USBJFields {
|
||||
USBJ_FIELD_MODE,
|
||||
USBJ_FIELD_INVERSION,
|
||||
USBJ_FIELD_SUBMODE,
|
||||
USBJ_FIELD_BTNPOS,
|
||||
USBJ_FIELD_BTNNUM,
|
||||
USBJ_FIELD_MAX
|
||||
};
|
||||
|
||||
void menuModelUSBJoystickOne(event_t event)
|
||||
{
|
||||
#if defined(KEYS_GPIO_REG_MDL)
|
||||
if (event == EVT_KEY_FIRST(KEY_MODEL)) {
|
||||
pushMenu(menuChannelsView);
|
||||
killEvents(event);
|
||||
}
|
||||
#elif defined(NAVIGATION_X7)
|
||||
if (event == EVT_KEY_FIRST(KEY_MENU)) {
|
||||
pushMenu(menuChannelsView);
|
||||
killEvents(event);
|
||||
}
|
||||
#elif defined(NAVIGATION_XLITE)
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER) && IS_SHIFT_PRESSED()) {
|
||||
pushMenu(menuChannelsView);
|
||||
killEvents(event);
|
||||
}
|
||||
#endif
|
||||
USBJoystickChData * cch = usbJChAddress(s_currIdx);
|
||||
putsChn(12*FW, 0, s_currIdx+1, 0);
|
||||
lcdDrawNumber(20*FW, 0, channelOutputs[s_currIdx], RIGHT);
|
||||
|
||||
SUBMENU(STR_USBJOYSTICK_LABEL, USBJ_FIELD_MAX, {
|
||||
0,
|
||||
(cch->mode != USBJOYS_CH_NONE) ? (uint8_t)0 : (uint8_t)HIDDEN_ROW,
|
||||
(cch->mode != USBJOYS_CH_NONE) ? (uint8_t)0 : (uint8_t)HIDDEN_ROW,
|
||||
(cch->mode == USBJOYS_CH_BUTTON) ?
|
||||
(((cch->param == USBJOYS_BTN_MODE_SW_EMU) || (cch->param == USBJOYS_BTN_MODE_DELTA)) ? (uint8_t)READONLY_ROW : (uint8_t)0)
|
||||
: (uint8_t)HIDDEN_ROW,
|
||||
(cch->mode == USBJOYS_CH_BUTTON) ? (uint8_t)0 : (uint8_t)HIDDEN_ROW });
|
||||
|
||||
int8_t sub = menuVerticalPosition;
|
||||
|
||||
char str[20];
|
||||
|
||||
for (uint8_t i=0; i<(NUM_BODY_LINES-1); i++) {
|
||||
coord_t y = MENU_HEADER_HEIGHT + 1 + i*FH;
|
||||
uint8_t k = i + menuVerticalOffset;
|
||||
for (int j=0; j<=k; ++j) {
|
||||
if (j<(int)DIM(mstate_tab) && mstate_tab[j] == HIDDEN_ROW) {
|
||||
++k;
|
||||
}
|
||||
}
|
||||
LcdFlags attr = (sub==k ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0);
|
||||
|
||||
switch (k) {
|
||||
case USBJ_FIELD_MODE:
|
||||
cch->mode = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_MODE, STR_VUSBJOYSTICK_CH_MODE, cch->mode, 0, USBJOYS_CH_LAST, attr, event);
|
||||
break;
|
||||
|
||||
case USBJ_FIELD_INVERSION:
|
||||
lcdDrawTextAlignedLeft(y, TR_USBJOYSTICK_CH_INVERSION);
|
||||
drawCheckBox(USBJ_ONE_2ND_COLUMN, y, cch->inversion, attr);
|
||||
if (attr) cch->inversion = checkIncDecModel(event, cch->inversion, 0, 1);
|
||||
break;
|
||||
|
||||
case USBJ_FIELD_SUBMODE:
|
||||
if(cch->mode == USBJOYS_CH_BUTTON) {
|
||||
cch->param = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_BTNMODE, STR_VUSBJOYSTICK_CH_BTNMODE, cch->param, 0, USBJOYS_BTN_MODE_LAST, attr, event);
|
||||
if(cch->param == USBJOYS_BTN_MODE_SW_EMU) cch->switch_npos = 0;
|
||||
else if(cch->param == USBJOYS_BTN_MODE_DELTA) cch->switch_npos = 1;
|
||||
}
|
||||
else if(cch->mode == USBJOYS_CH_AXIS) {
|
||||
cch->param = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_AXIS, STR_VUSBJOYSTICK_CH_AXIS, cch->param, 0, USBJOYS_AXIS_LAST, attr, event);
|
||||
}
|
||||
else if(cch->mode == USBJOYS_CH_SIM) {
|
||||
cch->param = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_SIM, STR_VUSBJOYSTICK_CH_SIM, cch->param, 0, USBJOYS_SIM_LAST, attr, event);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBJ_FIELD_BTNPOS:
|
||||
if(cch->param == USBJOYS_BTN_MODE_SW_EMU) {
|
||||
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_CH_SWPOS);
|
||||
lcdDrawText(USBJ_ONE_2ND_COLUMN, y, STR_VUSBJOYSTICK_CH_SWPOS[0], attr);
|
||||
}
|
||||
else if(cch->param == USBJOYS_BTN_MODE_DELTA) {
|
||||
lcdDrawTextAlignedLeft(y, STR_USBJOYSTICK_CH_SWPOS);
|
||||
lcdDrawText(USBJ_ONE_2ND_COLUMN, y, STR_VUSBJOYSTICK_CH_SWPOS[1], attr);
|
||||
}
|
||||
else {
|
||||
cch->switch_npos = editChoice(USBJ_ONE_2ND_COLUMN, y, STR_USBJOYSTICK_CH_SWPOS, STR_VUSBJOYSTICK_CH_SWPOS, cch->switch_npos, 0, 7, attr, event);
|
||||
}
|
||||
break;
|
||||
|
||||
case USBJ_FIELD_BTNNUM:
|
||||
lcdDrawTextAlignedLeft(y, TR_USBJOYSTICK_CH_BTNNUM);
|
||||
uint8_t last = cch->lastBtnNumNoCLip();
|
||||
uint8_t limited = 0;
|
||||
if(last >= USBJ_BUTTON_SIZE) {
|
||||
limited = 1;
|
||||
last = USBJ_BUTTON_SIZE-1;
|
||||
}
|
||||
if (last > cch->btn_num)
|
||||
snprintf(str, 20, "%u..%u%c", cch->btn_num, last, limited ? '!' : ' ');
|
||||
else
|
||||
snprintf(str, 20, "%u%c", cch->btn_num, limited ? '!' : ' ');
|
||||
lcdDrawText(USBJ_ONE_2ND_COLUMN, y, str, attr);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR(event, cch->btn_num, 0, USBJ_BUTTON_SIZE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cch->mode == USBJOYS_CH_BUTTON) {
|
||||
if (isUSBBtnNumCollision(s_currIdx)) {
|
||||
lcdDrawText(LCD_W/2, LCD_H-FH, STR_USBJOYSTICK_BTN_COLLISION, INVERS | CENTERED);
|
||||
}
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_AXIS) {
|
||||
if (isUSBAxisCollision(s_currIdx)) {
|
||||
lcdDrawText(LCD_W/2, LCD_H-FH, STR_USBJOYSTICK_AXIS_COLLISION, INVERS | CENTERED);
|
||||
}
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_SIM) {
|
||||
if (isUSBSimCollision(s_currIdx)) {
|
||||
lcdDrawText(LCD_W/2, LCD_H-FH, STR_USBJOYSTICK_AXIS_COLLISION, INVERS | CENTERED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void onUSBJoystickMenu(const char *result)
|
||||
{
|
||||
int8_t sub = menuVerticalPosition - HEADER_LINE;
|
||||
USBJoystickChData * cs = usbJChAddress(sub);
|
||||
|
||||
if (result == STR_EDIT) {
|
||||
s_currIdx = sub;
|
||||
pushMenu(menuModelUSBJoystickOne);
|
||||
}
|
||||
else if (result == STR_CLEAR) {
|
||||
memset(cs, 0, sizeof(USBJoystickChData));
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
}
|
||||
|
||||
void menuModelUSBJoystick(event_t event)
|
||||
{
|
||||
check_submenu_simple(event, USBJ_MAX_JOYSTICK_CHANNELS - HEADER_LINE);
|
||||
title(STR_USBJOYSTICK_LABEL);
|
||||
|
||||
if (s_editMode > 0) s_editMode = 0;
|
||||
|
||||
int8_t sub = menuVerticalPosition - HEADER_LINE;
|
||||
|
||||
coord_t y = 0;
|
||||
uint8_t k = 0;
|
||||
|
||||
if (event == EVT_KEY_FIRST(KEY_ENTER)) {
|
||||
killEvents(event);
|
||||
USBJoystickChData * cch = usbJChAddress(sub);
|
||||
s_currIdx = sub;
|
||||
if (sub >= 0)
|
||||
POPUP_MENU_ADD_ITEM(STR_EDIT);
|
||||
if (cch->mode != USBJOYS_CH_NONE)
|
||||
POPUP_MENU_ADD_ITEM(STR_CLEAR);
|
||||
if (popupMenuItemsCount == 1) {
|
||||
popupMenuItemsCount = 0;
|
||||
s_currIdx = sub;
|
||||
pushMenu(menuModelUSBJoystickOne);
|
||||
}
|
||||
else {
|
||||
POPUP_MENU_START(onUSBJoystickMenu);
|
||||
}
|
||||
}
|
||||
|
||||
char str[20];
|
||||
|
||||
for (uint8_t i=0; i<NUM_BODY_LINES; i++) {
|
||||
y = MENU_HEADER_HEIGHT + 1 + i*FH;
|
||||
k = i + menuVerticalOffset;
|
||||
LcdFlags attr = (sub==k) ? INVERS : 0;
|
||||
|
||||
USBJoystickChData * cch = usbJChAddress(k);
|
||||
|
||||
putsChn(0, y, k+1, attr);
|
||||
lcdDrawChar(4*FW, y, cch->inversion ? '{' : ' ', 0);
|
||||
|
||||
lcdDrawTextAtIndex(MODE_POS, y, STR_VUSBJOYSTICK_CH_MODE_S, cch->mode, 0);
|
||||
if (cch->mode == USBJOYS_CH_BUTTON) {
|
||||
lcdDrawTextAtIndex(SUBMODE_POS, y, STR_VUSBJOYSTICK_CH_SWPOS, cch->switch_npos, 0);
|
||||
lcdDrawTextAtIndex(BTNMODE_POS, y, STR_VUSBJOYSTICK_CH_BTNMODE_S, cch->param, 0);
|
||||
|
||||
uint8_t last = cch->lastBtnNum();
|
||||
if (last > cch->btn_num)
|
||||
sprintf(str, "%u..%u", cch->btn_num, last);
|
||||
else
|
||||
sprintf(str, "%u", cch->btn_num);
|
||||
LcdFlags warn = 0;
|
||||
if (isUSBBtnNumCollision(k)) warn = INVERS;
|
||||
lcdDrawText(BTNNUM_POS, y, str, RIGHT|warn);
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_AXIS) {
|
||||
LcdFlags warn = 0;
|
||||
if (isUSBAxisCollision(k)) warn = INVERS;
|
||||
lcdDrawTextAtIndex(SUBMODE_POS, y, STR_VUSBJOYSTICK_CH_AXIS, cch->param, warn);
|
||||
}
|
||||
else if (cch->mode == USBJOYS_CH_SIM) {
|
||||
LcdFlags warn = 0;
|
||||
if (isUSBSimCollision(k)) warn = INVERS;
|
||||
lcdDrawTextAtIndex(SUBMODE_POS, y, STR_VUSBJOYSTICK_CH_SIM, cch->param, warn);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -293,6 +293,11 @@ LimitData *limitAddress(uint8_t idx)
|
||||
return &g_model.limitData[idx];
|
||||
}
|
||||
|
||||
USBJoystickChData *usbJChAddress(uint8_t idx)
|
||||
{
|
||||
return &g_model.usbJoystickCh[idx];
|
||||
}
|
||||
|
||||
|
||||
void memswap(void * a, void * b, uint8_t size)
|
||||
{
|
||||
|
||||
@@ -690,6 +690,7 @@ ExpoData * expoAddress(uint8_t idx);
|
||||
MixData * mixAddress(uint8_t idx);
|
||||
LimitData * limitAddress(uint8_t idx);
|
||||
LogicalSwitchData * lswAddress(uint8_t idx);
|
||||
USBJoystickChData * usbJChAddress(uint8_t idx);
|
||||
|
||||
void applyDefaultTemplate();
|
||||
void instantTrim();
|
||||
|
||||
@@ -35,6 +35,10 @@ using std::list;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
#endif
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "datastructs.h"
|
||||
@@ -1330,6 +1334,10 @@ void ModelsList::setCurrentModel(ModelCell *cell)
|
||||
gettime(&t);
|
||||
cell->lastOpened = gmktime(&t);
|
||||
modelslabels.setDirty();
|
||||
|
||||
#if defined(USBJ_EX) && defined(STM32) && !defined(SIMU)
|
||||
onUSBJoystickModelChanged();
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,6 +22,10 @@
|
||||
#include "opentx.h"
|
||||
#include "timers_driver.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
#endif
|
||||
|
||||
#if defined(MULTIMODULE)
|
||||
#include "pulses/multi.h"
|
||||
#if defined(MULTI_PROTOLIST)
|
||||
@@ -214,6 +218,10 @@ void selectModel(uint8_t idx)
|
||||
g_eeGeneral.currModel = idx;
|
||||
storageDirty(EE_GENERAL);
|
||||
loadModel(idx);
|
||||
|
||||
#if defined(USBJ_EX) && defined(STM32) && !defined(SIMU)
|
||||
onUSBJoystickModelChanged();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t findEmptyModel(uint8_t id, bool down)
|
||||
|
||||
@@ -261,6 +261,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -812,6 +825,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -865,6 +887,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -271,6 +271,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -842,6 +855,15 @@ static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("options", 96, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
@@ -895,6 +917,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_STRUCT("topbarData", 1248, struct_TopBarPersistentData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -268,6 +268,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -817,6 +830,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -875,6 +897,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_UNSIGNED( "functionSwitchStartConfig", 16 ),
|
||||
YAML_UNSIGNED( "functionSwitchLogicalState", 8 ),
|
||||
YAML_ARRAY("switchNames", 24, 6, struct_string_24, NULL),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -302,6 +302,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -873,6 +886,15 @@ static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("options", 96, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
@@ -926,6 +948,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_STRUCT("topbarData", 2400, struct_TopBarPersistentData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -300,6 +300,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -871,6 +884,15 @@ static const struct YamlNode struct_TopBarPersistentData[] = {
|
||||
YAML_ARRAY("options", 96, 1, struct_ZoneOptionValueTyped, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 1048, struct_ModelHeader, NULL),
|
||||
@@ -924,6 +946,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_STRUCT("topbarData", 2400, struct_TopBarPersistentData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -267,6 +267,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -824,6 +837,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 192, struct_ModelHeader, NULL),
|
||||
@@ -879,6 +901,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -306,6 +306,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -863,6 +876,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 192, struct_ModelHeader, NULL),
|
||||
@@ -919,6 +941,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -247,6 +247,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -796,6 +809,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -849,6 +871,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -255,6 +255,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -806,6 +819,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -859,6 +881,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -252,6 +252,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -803,6 +816,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -856,6 +878,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -254,6 +254,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -807,6 +820,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -860,6 +882,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -260,6 +260,19 @@ const struct YamlIdStr enum_TelemetrySensorType[] = {
|
||||
{ TELEM_TYPE_CALCULATED, "TYPE_CALCULATED" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickIfMode[] = {
|
||||
{ USBJOYS_JOYSTICK, "JOYSTICK" },
|
||||
{ USBJOYS_GAMEPAD, "GAMEPAD" },
|
||||
{ USBJOYS_MULTIAXIS, "MULTIAXIS" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
const struct YamlIdStr enum_USBJoystickCh[] = {
|
||||
{ USBJOYS_CH_NONE, "CH_NONE" },
|
||||
{ USBJOYS_CH_BUTTON, "CH_BUTTON" },
|
||||
{ USBJOYS_CH_AXIS, "CH_AXIS" },
|
||||
{ USBJOYS_CH_SIM, "CH_SIM" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
//
|
||||
// Structs last
|
||||
@@ -811,6 +824,15 @@ static const struct YamlNode struct_TelemetryScreenData[] = {
|
||||
YAML_UNION("u", 192, union_TelemetryScreenData_u_elmts, select_tele_screen_data),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_USBJoystickChData[] = {
|
||||
YAML_IDX,
|
||||
YAML_ENUM("mode", 3, enum_USBJoystickCh),
|
||||
YAML_UNSIGNED( "inversion", 1 ),
|
||||
YAML_UNSIGNED( "param", 4 ),
|
||||
YAML_UNSIGNED( "btn_num", 5 ),
|
||||
YAML_UNSIGNED( "switch_npos", 3 ),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_CUSTOM("semver",nullptr,w_semver),
|
||||
YAML_STRUCT("header", 96, struct_ModelHeader, NULL),
|
||||
@@ -864,6 +886,10 @@ static const struct YamlNode struct_ModelData[] = {
|
||||
YAML_ARRAY("screens", 192, 4, struct_TelemetryScreenData, NULL),
|
||||
YAML_UNSIGNED( "view", 8 ),
|
||||
YAML_STRING("modelRegistrationID", 8),
|
||||
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
|
||||
YAML_ENUM("usbJoystickIfMode", 3, enum_USBJoystickIfMode),
|
||||
YAML_UNSIGNED( "usbJoystickCircularCut", 4 ),
|
||||
YAML_ARRAY("usbJoystickCh", 16, 26, struct_USBJoystickChData, NULL),
|
||||
YAML_END
|
||||
};
|
||||
static const struct YamlNode struct_PartialModel[] = {
|
||||
|
||||
@@ -21,6 +21,10 @@
|
||||
|
||||
#include "usb_driver.h"
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
#include "usb_conf.h"
|
||||
#include "usb_dcd_int.h"
|
||||
@@ -83,6 +87,9 @@ void usbStart()
|
||||
#if !defined(BOOT)
|
||||
case USB_JOYSTICK_MODE:
|
||||
// initialize USB as HID device
|
||||
#if defined(USBJ_EX)
|
||||
setupUSBJoystick();
|
||||
#endif
|
||||
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_HID_cb, &USR_cb);
|
||||
break;
|
||||
#endif
|
||||
@@ -108,6 +115,18 @@ void usbStop()
|
||||
USBD_DeInit(&USB_OTG_dev);
|
||||
}
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
void usbJoystickRestart()
|
||||
{
|
||||
if (getSelectedUsbMode() != USB_JOYSTICK_MODE) return;
|
||||
|
||||
USBD_DeInit(&USB_OTG_dev);
|
||||
DCD_DevDisconnect(&USB_OTG_dev);
|
||||
DCD_DevConnect(&USB_OTG_dev);
|
||||
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_HID_cb, &USR_cb);
|
||||
}
|
||||
#endif
|
||||
|
||||
bool usbStarted()
|
||||
{
|
||||
return usbDriverStarted;
|
||||
@@ -125,6 +144,7 @@ bool usbStarted()
|
||||
*/
|
||||
void usbJoystickUpdate()
|
||||
{
|
||||
#if !defined(USBJ_EX)
|
||||
static uint8_t HID_Buffer[HID_IN_PACKET];
|
||||
|
||||
// test to se if TX buffer is free
|
||||
@@ -158,5 +178,12 @@ void usbJoystickUpdate()
|
||||
}
|
||||
USBD_HID_SendReport(&USB_OTG_dev, HID_Buffer, HID_IN_PACKET);
|
||||
}
|
||||
#else
|
||||
// test to se if TX buffer is free
|
||||
if (USBD_HID_SendReport(&USB_OTG_dev, 0, 0) == USBD_OK) {
|
||||
usbReport_t ret = usbReport();
|
||||
USBD_HID_SendReport(&USB_OTG_dev, ret.ptr, ret.size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -48,6 +48,9 @@ int usbPlugged();
|
||||
void usbInit();
|
||||
void usbStart();
|
||||
void usbStop();
|
||||
#if defined(USBJ_EX)
|
||||
void usbJoystickRestart();
|
||||
#endif
|
||||
bool usbStarted();
|
||||
|
||||
EXTERN_C(int getSelectedUsbMode());
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
#define HID_IN_EP 0x81
|
||||
#define HID_OUT_EP 0x01
|
||||
|
||||
#if !defined(USBJ_EX)
|
||||
#define HID_IN_PACKET 19
|
||||
#endif
|
||||
#define HID_OUT_PACKET 9
|
||||
|
||||
#define CDC_IN_EP 0x81 /* EP1 for data IN */
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#include "usbd_desc.h"
|
||||
#include "usbd_hid_core.h"
|
||||
#include "usbd_req.h"
|
||||
#if defined(USBJ_EX)
|
||||
#include "usb_joystick.h"
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32_USB_OTG_DEVICE_LIBRARY
|
||||
* @{
|
||||
@@ -88,6 +91,8 @@ static uint8_t USBD_HID_DataIn (void *pdev, uint8_t epnum);
|
||||
#pragma data_alignment=4
|
||||
#endif
|
||||
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
|
||||
|
||||
#if !defined(USBJ_EX)
|
||||
/*
|
||||
This USB HID endpoint report description defines a device with:
|
||||
* 24 digital buttons
|
||||
@@ -140,7 +145,7 @@ __ALIGN_BEGIN static const uint8_t HID_JOYSTICK_ReportDesc[] __ALIGN_END =
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/** @defgroup USBD_HID_Private_Variables
|
||||
* @{
|
||||
@@ -191,7 +196,7 @@ __ALIGN_BEGIN static uint32_t USBD_HID_IdleState __ALIGN_END = 0;
|
||||
#endif
|
||||
#endif /* USB_OTG_HS_INTERNAL_DMA_ENABLED */
|
||||
/* USB HID device Configuration Descriptor */
|
||||
__ALIGN_BEGIN static const uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END =
|
||||
{
|
||||
0x09, /* bLength: Configuration Descriptor size */
|
||||
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType: Configuration */
|
||||
@@ -225,7 +230,11 @@ __ALIGN_BEGIN static const uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __A
|
||||
0x00, /*bCountryCode: Hardware target country*/
|
||||
0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/
|
||||
0x22, /*bDescriptorType*/
|
||||
#if !defined(USBJ_EX)
|
||||
sizeof(HID_JOYSTICK_ReportDesc),/*wItemLength: Total length of Report descriptor*/
|
||||
#else
|
||||
0,/*wItemLength: Total length of Report descriptor*/
|
||||
#endif
|
||||
0x00,
|
||||
/******************** Descriptor of Mouse endpoint ********************/
|
||||
/* 27 */
|
||||
@@ -234,7 +243,11 @@ __ALIGN_BEGIN static const uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __A
|
||||
|
||||
HID_IN_EP, /*bEndpointAddress: Endpoint Address (IN)*/
|
||||
0x03, /*bmAttributes: Interrupt endpoint*/
|
||||
#if !defined(USBJ_EX)
|
||||
HID_IN_PACKET, /*wMaxPacketSize: 4 Byte max */
|
||||
#else
|
||||
0,/*HID_IN_PACKET,*/ /*wMaxPacketSize*/
|
||||
#endif
|
||||
0x00,
|
||||
0x01, /*bInterval: Polling Interval (1 ms)*/
|
||||
/* 34 */
|
||||
@@ -262,11 +275,18 @@ static uint8_t ReportSent;
|
||||
static uint8_t USBD_HID_Init (void *pdev,
|
||||
uint8_t cfgidx)
|
||||
{
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
uint8_t hid_in_pkt_size = usbReportSize();
|
||||
#endif
|
||||
|
||||
/* Open EP IN */
|
||||
DCD_EP_Open(pdev,
|
||||
HID_IN_EP,
|
||||
#if !defined(USBJ_EX)
|
||||
HID_IN_PACKET,
|
||||
#else
|
||||
hid_in_pkt_size /*HID_IN_PACKET*/,
|
||||
#endif
|
||||
USB_OTG_EP_INT);
|
||||
|
||||
/* Open EP OUT */
|
||||
@@ -349,8 +369,14 @@ static uint8_t USBD_HID_Setup (void *pdev,
|
||||
case USB_REQ_GET_DESCRIPTOR:
|
||||
if( req->wValue >> 8 == HID_REPORT_DESC)
|
||||
{
|
||||
#if !defined(USBJ_EX)
|
||||
len = MIN(sizeof(HID_JOYSTICK_ReportDesc) , req->wLength);
|
||||
pbuf = HID_JOYSTICK_ReportDesc; // wiiccReportDescriptor; //
|
||||
#else
|
||||
struct usbReport_t ret = usbReportDesc();
|
||||
len = MIN(ret.size, req->wLength);
|
||||
pbuf = ret.ptr;
|
||||
#endif
|
||||
}
|
||||
else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE)
|
||||
{
|
||||
@@ -414,6 +440,12 @@ uint8_t USBD_HID_SendReport(USB_OTG_CORE_HANDLE *pdev, uint8_t * report, uint16
|
||||
*/
|
||||
static const uint8_t *USBD_HID_GetCfgDesc (uint8_t speed, uint16_t *length)
|
||||
{
|
||||
#if defined(USBJ_EX)
|
||||
struct usbReport_t ret = usbReportDesc();
|
||||
USBD_HID_CfgDesc[25] = ret.size;
|
||||
USBD_HID_CfgDesc[31] = usbReportSize();
|
||||
#endif
|
||||
|
||||
*length = sizeof (USBD_HID_CfgDesc);
|
||||
return USBD_HID_CfgDesc;
|
||||
}
|
||||
|
||||
@@ -949,3 +949,31 @@ const char STR_MAIN_MENU_STATISTICS[] = TR_MAIN_MENU_STATISTICS;
|
||||
const char STR_MAIN_MENU_ABOUT_EDGETX[] = TR_MAIN_MENU_ABOUT_EDGETX;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
const char STR_USBJOYSTICK_LABEL[] = TR_USBJOYSTICK_LABEL;
|
||||
const char STR_USBJOYSTICK_EXTMODE[] = TR_USBJOYSTICK_EXTMODE;
|
||||
ISTR(VUSBJOYSTICK_EXTMODE);
|
||||
const char STR_USBJOYSTICK_SETTINGS[] = TR_USBJOYSTICK_SETTINGS;
|
||||
const char STR_USBJOYSTICK_IF_MODE[] = TR_USBJOYSTICK_IF_MODE;
|
||||
ISTR(VUSBJOYSTICK_IF_MODE);
|
||||
const char STR_USBJOYSTICK_CH_MODE[] = TR_USBJOYSTICK_CH_MODE;
|
||||
ISTR(VUSBJOYSTICK_CH_MODE);
|
||||
ISTR(VUSBJOYSTICK_CH_MODE_S);
|
||||
const char STR_USBJOYSTICK_CH_BTNMODE[] = TR_USBJOYSTICK_CH_BTNMODE;
|
||||
ISTR(VUSBJOYSTICK_CH_BTNMODE);
|
||||
ISTR(VUSBJOYSTICK_CH_BTNMODE_S);
|
||||
const char STR_USBJOYSTICK_CH_SWPOS[] = TR_USBJOYSTICK_CH_SWPOS;
|
||||
ISTR(VUSBJOYSTICK_CH_SWPOS);
|
||||
const char STR_USBJOYSTICK_CH_AXIS[] = TR_USBJOYSTICK_CH_AXIS;
|
||||
ISTR(VUSBJOYSTICK_CH_AXIS);
|
||||
const char STR_USBJOYSTICK_CH_SIM[] = TR_USBJOYSTICK_CH_SIM;
|
||||
ISTR(VUSBJOYSTICK_CH_SIM);
|
||||
const char STR_USBJOYSTICK_CH_INVERSION[] = TR_USBJOYSTICK_CH_INVERSION;
|
||||
const char STR_USBJOYSTICK_CH_BTNNUM[] = TR_USBJOYSTICK_CH_BTNNUM;
|
||||
const char STR_USBJOYSTICK_BTN_COLLISION[] = TR_USBJOYSTICK_BTN_COLLISION;
|
||||
const char STR_USBJOYSTICK_AXIS_COLLISION[] = TR_USBJOYSTICK_AXIS_COLLISION;
|
||||
const char STR_USBJOYSTICK_CIRC_COUTOUT[] = TR_USBJOYSTICK_CIRC_COUTOUT;
|
||||
ISTR(VUSBJOYSTICK_CIRC_COUTOUT);
|
||||
const char STR_USBJOYSTICK_APPLY_CHANGES[] = TR_USBJOYSTICK_APPLY_CHANGES;
|
||||
#endif
|
||||
|
||||
@@ -1122,5 +1122,33 @@ extern const char STR_MAIN_MENU_ABOUT_EDGETX[];
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USBJ_EX)
|
||||
extern const char STR_USBJOYSTICK_LABEL[];
|
||||
extern const char STR_USBJOYSTICK_EXTMODE[];
|
||||
extern const char* const STR_VUSBJOYSTICK_EXTMODE[];
|
||||
extern const char STR_USBJOYSTICK_SETTINGS[];
|
||||
extern const char STR_USBJOYSTICK_IF_MODE[];
|
||||
extern const char* const STR_VUSBJOYSTICK_IF_MODE[];
|
||||
extern const char STR_USBJOYSTICK_CH_MODE[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_MODE[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_MODE_S[];
|
||||
extern const char STR_USBJOYSTICK_CH_BTNMODE[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_BTNMODE[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_BTNMODE_S[];
|
||||
extern const char STR_USBJOYSTICK_CH_SWPOS[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_SWPOS[];
|
||||
extern const char STR_USBJOYSTICK_CH_AXIS[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_AXIS[];
|
||||
extern const char STR_USBJOYSTICK_CH_SIM[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CH_SIM[];
|
||||
extern const char STR_USBJOYSTICK_CH_INVERSION[];
|
||||
extern const char STR_USBJOYSTICK_CH_BTNNUM[];
|
||||
extern const char STR_USBJOYSTICK_BTN_COLLISION[];
|
||||
extern const char STR_USBJOYSTICK_AXIS_COLLISION[];
|
||||
extern const char STR_USBJOYSTICK_CIRC_COUTOUT[];
|
||||
extern const char* const STR_VUSBJOYSTICK_CIRC_COUTOUT[];
|
||||
extern const char STR_USBJOYSTICK_APPLY_CHANGES[];
|
||||
#endif
|
||||
|
||||
#endif // _TRANSLATIONS_H_
|
||||
|
||||
|
||||
@@ -1237,3 +1237,29 @@
|
||||
#define TR_VOICE_SWEDISH "瑞典语"
|
||||
#define TR_VOICE_TAIWANESE "中文-台湾国语"
|
||||
#define TR_VOICE_JAPANESE "日文"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1239,3 +1239,29 @@
|
||||
#define TR_VOICE_SWEDISH "Švédština"
|
||||
#define TR_VOICE_TAIWANESE "Tchajwanština"
|
||||
#define TR_VOICE_JAPANESE "Japonština"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1252,3 +1252,29 @@
|
||||
#define TR_VOICE_SWEDISH "Svensk"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanesisk"
|
||||
#define TR_VOICE_JAPANESE "Japansk"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB joystik"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Tilstand"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Klassisk","Advanceret"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Kanal indstillinger"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("Intf. tils.","Interface tilstand")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystik","Gamepad","MultiAkse"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Tilstand"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "Ingen","Knap","Akse","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Knap tilstand"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positioner"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Skub","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Akse"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Skyder","Drej","Hjul"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim akse"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Kræ","Høj","Sid","Gas"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Omvendt"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Knap #"
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Knap # kollision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Akse kollision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Cirk. klip", "Cikulær klip")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "Ingen","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Gem ændringer"
|
||||
|
||||
@@ -1238,3 +1238,29 @@
|
||||
#define TR_VOICE_SWEDISH "Schwedisch"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanisch"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1231,3 +1231,29 @@
|
||||
#define TR_VOICE_SWEDISH "Swedish"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1242,3 +1242,29 @@
|
||||
#define TR_VOICE_SWEDISH "Swedish"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1255,3 +1255,29 @@
|
||||
#define TR_VOICE_SWEDISH "Swedish"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1260,3 +1260,29 @@
|
||||
#define TR_VOICE_SWEDISH "Swedish"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1247,3 +1247,29 @@
|
||||
#define TR_VOICE_SWEDISH "Svedese"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Giapponese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1232,3 +1232,29 @@
|
||||
#define TR_VOICE_SWEDISH "スウェーデン-SV"
|
||||
#define TR_VOICE_TAIWANESE "中文-TW"
|
||||
#define TR_VOICE_JAPANESE "日本-JP"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1252,3 +1252,29 @@
|
||||
#define TR_VOICE_SWEDISH "Swedish"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1236,3 +1236,29 @@
|
||||
#define TR_VOICE_SWEDISH "Szwedzki"
|
||||
#define TR_VOICE_TAIWANESE "Tajwański"
|
||||
#define TR_VOICE_JAPANESE "Japonês"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1245,3 +1245,29 @@
|
||||
#define TR_VOICE_SWEDISH "Swedish"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanese"
|
||||
#define TR_VOICE_JAPANESE "Japanese"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1278,3 +1278,29 @@
|
||||
#define TR_VOICE_SWEDISH "Svenska"
|
||||
#define TR_VOICE_TAIWANESE "Taiwanesiska"
|
||||
#define TR_VOICE_JAPANESE "Japanska"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -1235,3 +1235,29 @@
|
||||
#define TR_VOICE_SWEDISH "瑞典語"
|
||||
#define TR_VOICE_TAIWANESE "中文-台灣國語"
|
||||
#define TR_VOICE_JAPANESE "日文"
|
||||
|
||||
#define TR_USBJOYSTICK_LABEL "USB Joystick"
|
||||
#define TR_USBJOYSTICK_EXTMODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_EXTMODE "Classic","Advanced"
|
||||
#define TR_USBJOYSTICK_SETTINGS "Channel Settings"
|
||||
#define TR_USBJOYSTICK_IF_MODE TR("If. mode","Interface mode")
|
||||
#define TR_VUSBJOYSTICK_IF_MODE "Joystick","Gamepad","MultiAxis"
|
||||
#define TR_USBJOYSTICK_CH_MODE "Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE "None","Btn","Axis","Sim"
|
||||
#define TR_VUSBJOYSTICK_CH_MODE_S "-","B","A","S"
|
||||
#define TR_USBJOYSTICK_CH_BTNMODE "Button Mode"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE "Normal","Pulse","SWEmu","Delta","Companion"
|
||||
#define TR_VUSBJOYSTICK_CH_BTNMODE_S TR("Norm","Normal"),TR("Puls","Pulse"),TR("SWEm","SWEmul"),TR("Delt","Delta"),TR("CPN","Companion")
|
||||
#define TR_USBJOYSTICK_CH_SWPOS "Positions"
|
||||
#define TR_VUSBJOYSTICK_CH_SWPOS "Push","2POS","3POS","4POS","5POS","6POS","7POS","8POS"
|
||||
#define TR_USBJOYSTICK_CH_AXIS "Axis"
|
||||
#define TR_VUSBJOYSTICK_CH_AXIS "X","Y","Z","rotX","rotY","rotZ","Slider","Dial","Wheel"
|
||||
#define TR_USBJOYSTICK_CH_SIM "Sim axis"
|
||||
#define TR_VUSBJOYSTICK_CH_SIM "Ail","Ele","Rud","Thr"
|
||||
#define TR_USBJOYSTICK_CH_INVERSION "Inversion"
|
||||
#define TR_USBJOYSTICK_CH_BTNNUM "Button no."
|
||||
#define TR_USBJOYSTICK_BTN_COLLISION "!Button no. collision!"
|
||||
#define TR_USBJOYSTICK_AXIS_COLLISION "!Axis collision!"
|
||||
#define TR_USBJOYSTICK_CIRC_COUTOUT TR("Circ. cut", "Circular cutout")
|
||||
#define TR_VUSBJOYSTICK_CIRC_COUTOUT "None","X-Y, Z-rX","X-Y, rX-rY"
|
||||
#define TR_USBJOYSTICK_APPLY_CHANGES "Apply changes"
|
||||
|
||||
@@ -0,0 +1,758 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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 "opentx.h"
|
||||
#include "usb_joystick.h"
|
||||
|
||||
#define MAX_HID_REPORTDESC 160
|
||||
#define MAX_HID_REPORT 80
|
||||
|
||||
uint8_t _hidReportDesc[MAX_HID_REPORTDESC] = { };
|
||||
uint8_t _hidReportDescSize = 0;
|
||||
uint8_t _hidReport[MAX_HID_REPORT] = { };
|
||||
uint8_t _hidReportSize = 0;
|
||||
|
||||
static uint8_t _buttonState[USBJ_BUTTON_SIZE >> 3] = { };
|
||||
|
||||
static uint16_t _usbLastChannelOutput[USBJ_MAX_JOYSTICK_CHANNELS] = { };
|
||||
static uint8_t _usbChannelTimerActive[USBJ_MAX_JOYSTICK_CHANNELS] = { };
|
||||
static uint8_t _usbChannelTimer[USBJ_MAX_JOYSTICK_CHANNELS] = { };
|
||||
|
||||
static uint8_t _usbJoystickIfMode = 0;
|
||||
static uint8_t _usbJoystickCircularCut = 0;
|
||||
static USBJoystickChData _usbJoystickCh[USBJ_MAX_JOYSTICK_CHANNELS];
|
||||
|
||||
#define USBJ_CC_XYZrX 1
|
||||
#define USBJ_CC_XYrXrZ 2
|
||||
|
||||
static uint8_t _usbJoystickButtonChannels[USBJ_MAX_JOYSTICK_CHANNELS] = { };
|
||||
static uint8_t _usbJoystickButtonCount = 0;
|
||||
static uint8_t _usbJoystickAxisChannels[USBJ_MAX_JOYSTICK_CHANNELS] = { };
|
||||
static uint8_t _usbJoystickAxisCount = 0;
|
||||
|
||||
static uint8_t _usbJoystickAxisPairs[3][2] = { };
|
||||
|
||||
static const uint8_t _usbJoystickUniqueAxis[USBJOYS_AXIS_LAST + 1] =
|
||||
{ 1, 1, 1, 1, 1, 1, 0, 0, 0 };
|
||||
|
||||
static const uint8_t _usbJoystickUniqueSims[USBJOYS_SIM_LAST + 1] =
|
||||
{ 1, 1, 1, 1 };
|
||||
|
||||
/*
|
||||
This USB HID endpoint report description defines a device with:
|
||||
* 24 digital buttons
|
||||
* 8 analog axes with 8bit resolution
|
||||
|
||||
Repot packet described as C struct is:
|
||||
|
||||
struct {
|
||||
uint8_t buttons1; //bit 0 - button 1, bit 1 - button 2, ..., mapped to channels 9-16, on if channel > 0
|
||||
uint8_t buttons2; // mapped to channels 17-24, on if channel > 0
|
||||
uint8_t buttons3; // mapped to channels 25-32, on if channel > 0
|
||||
uint8_t X; //analog value, mapped to channel 1
|
||||
uint8_t Y; //analog value, mapped to channel 2
|
||||
uint8_t Z; //analog value, mapped to channel 3
|
||||
uint8_t Rx; //analog value, mapped to channel 4
|
||||
uint8_t Ry //analog value, mapped to channel 5
|
||||
uint8_t Rz; //analog value, mapped to channel 6
|
||||
uint8_t S1; //analog value, mapped to channel 7
|
||||
uint8_t S2; //analog value, mapped to channel 8
|
||||
}
|
||||
*/
|
||||
static const uint8_t HID_JOYSTICK_ReportDesc[] =
|
||||
{
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x05, // USAGE (Game Pad)
|
||||
0xa1, 0x01, // COLLECTION (Application)
|
||||
0xa1, 0x00, // COLLECTION (Physical)
|
||||
0x05, 0x09, // USAGE_PAGE (Button)
|
||||
0x19, 0x01, // USAGE_MINIMUM (Button 1)
|
||||
0x29, 0x18, // USAGE_MAXIMUM (Button 24)
|
||||
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
||||
0x95, 0x18, // REPORT_COUNT (24)
|
||||
0x75, 0x01, // REPORT_SIZE (1)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
||||
0x09, 0x30, // USAGE (X)
|
||||
0x09, 0x31, // USAGE (Y)
|
||||
0x09, 0x32, // USAGE (Z)
|
||||
0x09, 0x33, // USAGE (Rx)
|
||||
0x09, 0x34, // USAGE (Ry)
|
||||
0x09, 0x35, // USAGE (Rz)
|
||||
0x09, 0x36, // USAGE (Slider)
|
||||
0x09, 0x36, // USAGE (Slider)
|
||||
0x16, 0x00, 0x00, // LOGICAL_MINIMUM (0)
|
||||
0x26, 0xFF, 0x07, // LOGICAL_MAXIMUM (2047)
|
||||
0x75, 0x10, // REPORT_SIZE (16)
|
||||
0x95, 0x08, // REPORT_COUNT (8)
|
||||
0x81, 0x02, // INPUT (Data,Var,Abs)
|
||||
0xc0, // END_COLLECTION
|
||||
0xc0 // END_COLLECTION
|
||||
};
|
||||
|
||||
int usbJoystickExtMode()
|
||||
{
|
||||
return g_model.usbJoystickExtMode;
|
||||
}
|
||||
|
||||
int usbJoystickActive()
|
||||
{
|
||||
return (usbPlugged() && getSelectedUsbMode() == USB_JOYSTICK_MODE);
|
||||
}
|
||||
|
||||
int usbJoystickSettingsChanged()
|
||||
{
|
||||
if (!usbJoystickActive()) return false;
|
||||
|
||||
if((_usbJoystickIfMode != g_model.usbJoystickIfMode)
|
||||
|| (_usbJoystickCircularCut != g_model.usbJoystickCircularCut)) return true;
|
||||
if(memcmp(_usbJoystickCh, g_model.usbJoystickCh, sizeof(g_model.usbJoystickCh)) != 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int setupUSBJoystick()
|
||||
{
|
||||
static const uint8_t axisTypeCodes[USBJOYS_AXIS_LAST + 1] =
|
||||
{ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38 };
|
||||
static const uint8_t simTypeCodes[USBJOYS_SIM_LAST + 1] =
|
||||
{ 0xb0, 0xb8, 0xba, 0xbb };
|
||||
|
||||
static uint8_t oldHIDReportDesc[MAX_HID_REPORTDESC] = { };
|
||||
static uint8_t oldHIDReportDescSize = 0;
|
||||
|
||||
// copy old to compare
|
||||
memcpy(oldHIDReportDesc, _hidReportDesc, MAX_HID_REPORTDESC);
|
||||
oldHIDReportDescSize = _hidReportDescSize;
|
||||
|
||||
// copy the model snapshot
|
||||
_usbJoystickIfMode = g_model.usbJoystickIfMode;
|
||||
_usbJoystickCircularCut = g_model.usbJoystickCircularCut;
|
||||
memcpy(_usbJoystickCh, g_model.usbJoystickCh, sizeof(g_model.usbJoystickCh));
|
||||
|
||||
// Init data
|
||||
memset(_hidReportDesc, 0, MAX_HID_REPORTDESC);
|
||||
_hidReportDescSize = 0;
|
||||
memset(_hidReport, 0, MAX_HID_REPORT);
|
||||
_hidReportSize = 0;
|
||||
memset(_buttonState, 0, (USBJ_BUTTON_SIZE >> 3));
|
||||
memset(_usbLastChannelOutput, 0xff, sizeof(_usbLastChannelOutput));
|
||||
memset(_usbChannelTimer, 0, sizeof(_usbChannelTimer));
|
||||
memset(_usbChannelTimerActive, 0, sizeof(_usbChannelTimerActive));
|
||||
|
||||
memset(_usbJoystickButtonChannels, 0, USBJ_MAX_JOYSTICK_CHANNELS);
|
||||
_usbJoystickButtonCount = 0;
|
||||
memset(_usbJoystickAxisChannels, 0, USBJ_MAX_JOYSTICK_CHANNELS);
|
||||
_usbJoystickAxisCount = 0;
|
||||
memset(_usbJoystickAxisPairs, 0xff, sizeof(_usbJoystickAxisPairs));
|
||||
|
||||
if (!usbJoystickExtMode()) {
|
||||
// Classic USB Joystick report description
|
||||
memcpy(_hidReportDesc, HID_JOYSTICK_ReportDesc, sizeof(HID_JOYSTICK_ReportDesc));
|
||||
_hidReportDescSize = sizeof(HID_JOYSTICK_ReportDesc);
|
||||
_hidReportSize = 19;
|
||||
|
||||
} else {
|
||||
|
||||
uint8_t genAxisCount = 0;
|
||||
uint8_t simAxisCount = 0;
|
||||
|
||||
// sort channels by type
|
||||
uint8_t typeCount[USBJOYS_CH_LAST + 1] = { };
|
||||
uint8_t axisCount[USBJOYS_AXIS_LAST + 1] = { };
|
||||
uint8_t simCount[USBJOYS_SIM_LAST + 1] = { };
|
||||
uint8_t axisIx[USBJOYS_AXIS_LAST + 1] = { };
|
||||
uint8_t simIx[USBJOYS_SIM_LAST + 1] = { };
|
||||
uint8_t mode = 0;
|
||||
uint8_t submode = 0;
|
||||
for (uint8_t i = 0; i < USBJ_MAX_JOYSTICK_CHANNELS; i++) {
|
||||
mode = _usbJoystickCh[i].mode;
|
||||
|
||||
if (_usbJoystickCh[i].mode == USBJOYS_CH_BUTTON) {
|
||||
typeCount[mode]++;
|
||||
}
|
||||
else if (_usbJoystickCh[i].mode == USBJOYS_CH_AXIS) {
|
||||
submode = _usbJoystickCh[i].param;
|
||||
if (submode <= USBJOYS_AXIS_LAST) {
|
||||
if ((_usbJoystickUniqueAxis[submode] == 0) || (axisCount[submode] == 0)) {
|
||||
axisCount[submode]++;
|
||||
typeCount[mode]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_usbJoystickCh[i].mode == USBJOYS_CH_SIM) {
|
||||
submode = _usbJoystickCh[i].param;
|
||||
if (submode <= USBJOYS_SIM_LAST) {
|
||||
if ((_usbJoystickUniqueSims[submode] == 0) || (simCount[submode] == 0)) {
|
||||
simCount[submode]++;
|
||||
typeCount[mode]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uint8_t ixcount = 0;
|
||||
for (uint8_t i = 0; i <= USBJOYS_AXIS_LAST; i++) {
|
||||
axisIx[i] = ixcount;
|
||||
ixcount += axisCount[i];
|
||||
}
|
||||
ixcount = 0;
|
||||
for (uint8_t i = 0; i <= USBJOYS_SIM_LAST; i++) {
|
||||
simIx[i] = ixcount;
|
||||
ixcount += simCount[i];
|
||||
}
|
||||
ixcount = 0;
|
||||
for (uint8_t i = 0; i < USBJ_MAX_JOYSTICK_CHANNELS; i++) {
|
||||
mode = _usbJoystickCh[i].mode;
|
||||
|
||||
if (_usbJoystickCh[i].mode == USBJOYS_CH_BUTTON) {
|
||||
_usbJoystickButtonChannels[ixcount] = i;
|
||||
ixcount++;
|
||||
}
|
||||
else if (_usbJoystickCh[i].mode == USBJOYS_CH_AXIS) {
|
||||
submode = _usbJoystickCh[i].param;
|
||||
if (submode <= USBJOYS_AXIS_LAST) {
|
||||
_usbJoystickAxisChannels[axisIx[submode]] = i;
|
||||
if (_usbJoystickUniqueAxis[submode] == 0) {
|
||||
axisIx[submode]++;
|
||||
}
|
||||
// save axis pairs
|
||||
if(submode == USBJOYS_AXIS_X) {
|
||||
_usbJoystickAxisPairs[0][0] = i;
|
||||
}
|
||||
else if(submode == USBJOYS_AXIS_Y) {
|
||||
_usbJoystickAxisPairs[0][1] = i;
|
||||
}
|
||||
else if(submode == USBJOYS_AXIS_Z) {
|
||||
_usbJoystickAxisPairs[1][0] = i;
|
||||
}
|
||||
else if(submode == USBJOYS_AXIS_RX) {
|
||||
_usbJoystickAxisPairs[1][1] = i;
|
||||
_usbJoystickAxisPairs[2][0] = i;
|
||||
}
|
||||
else if(submode == USBJOYS_AXIS_RY) {
|
||||
_usbJoystickAxisPairs[2][1] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_usbJoystickCh[i].mode == USBJOYS_CH_SIM) {
|
||||
submode = _usbJoystickCh[i].param;
|
||||
if (submode <= USBJOYS_SIM_LAST) {
|
||||
_usbJoystickAxisChannels[simIx[submode]] = i;
|
||||
if (_usbJoystickUniqueSims[submode] == 0) {
|
||||
simIx[submode]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// store counts
|
||||
_usbJoystickButtonCount = typeCount[USBJOYS_CH_BUTTON];
|
||||
genAxisCount = typeCount[USBJOYS_CH_AXIS];
|
||||
simAxisCount = typeCount[USBJOYS_CH_SIM];
|
||||
_usbJoystickAxisCount = typeCount[USBJOYS_CH_AXIS] + typeCount[USBJOYS_CH_SIM];
|
||||
|
||||
// generate report desc
|
||||
|
||||
// USAGE_PAGE (Generic Desktop)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x05;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
// USAGE (Joystick=0x04, Gamepad=0x05, Multi-axis Controller=0x08)
|
||||
uint8_t joystickType = 0x04;
|
||||
if (_usbJoystickIfMode == USBJOYS_GAMEPAD) joystickType = 0x05;
|
||||
else if (_usbJoystickIfMode == USBJOYS_MULTIAXIS) joystickType = 0x08;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x09;
|
||||
_hidReportDesc[_hidReportDescSize++] = joystickType;
|
||||
|
||||
// COLLECTION (Application)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0xa1;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
// COLLECTION (Physical)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0xa1;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x00;
|
||||
|
||||
// REPORT_ID (1)
|
||||
// _hidReportDesc[_hidReportDescSize++] = 0x85;
|
||||
// _hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
// button types
|
||||
|
||||
// USAGE_PAGE (Button)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x05;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x09;
|
||||
|
||||
// USAGE_MINIMUM (Button 1)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x19;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
// USAGE_MAXIMUM (Button USBJ_BUTTON_SIZE)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x29;
|
||||
_hidReportDesc[_hidReportDescSize++] = USBJ_BUTTON_SIZE;
|
||||
|
||||
// LOGICAL_MINIMUM (0)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x15;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x00;
|
||||
|
||||
// LOGICAL_MAXIMUM (1)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x25;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
// REPORT_COUNT (#)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x95;
|
||||
_hidReportDesc[_hidReportDescSize++] = USBJ_BUTTON_SIZE;
|
||||
|
||||
// REPORT_SIZE (1)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x75;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
// INPUT (Data,Var,Abs,Preferred)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x81;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x02;
|
||||
|
||||
// generic axis types
|
||||
if (genAxisCount > 0) {
|
||||
|
||||
// USAGE_PAGE (Generic Desktop)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x05;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x01;
|
||||
|
||||
for (uint8_t i = 0; i <= USBJOYS_AXIS_LAST; i++) {
|
||||
for (uint8_t cnt = 0; cnt < axisCount[i]; cnt++) {
|
||||
// USAGE (#)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x09;
|
||||
_hidReportDesc[_hidReportDescSize++] = axisTypeCodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// LOGICAL_MINIMUM (0)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x16;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x00;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x00;
|
||||
|
||||
// LOGICAL_MAXIMUM (2047)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x26;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0xFF;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x07;
|
||||
|
||||
// REPORT_SIZE (16)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x75;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x10;
|
||||
|
||||
// REPORT_COUNT (#)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x95;
|
||||
_hidReportDesc[_hidReportDescSize++] = genAxisCount;
|
||||
|
||||
// INPUT (Data,Var,Abs)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x81;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x02;
|
||||
}
|
||||
|
||||
// sim axis types
|
||||
if (simAxisCount > 0) {
|
||||
|
||||
// USAGE_PAGE (Simulation Controls)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x05;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x02;
|
||||
|
||||
for (uint8_t i = 0; i <= USBJOYS_SIM_LAST; i++) {
|
||||
for (uint8_t cnt = 0; cnt < simCount[i]; cnt++) {
|
||||
// USAGE (#)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x09;
|
||||
_hidReportDesc[_hidReportDescSize++] = simTypeCodes[i];
|
||||
}
|
||||
}
|
||||
|
||||
// LOGICAL_MINIMUM (0)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x16;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x00;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x00;
|
||||
|
||||
// LOGICAL_MAXIMUM (2047)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x26;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0xFF;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x07;
|
||||
|
||||
// REPORT_SIZE (16)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x75;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x10;
|
||||
|
||||
// REPORT_COUNT (#)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x95;
|
||||
_hidReportDesc[_hidReportDescSize++] = simAxisCount;
|
||||
|
||||
// INPUT (Data,Var,Abs)
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x81;
|
||||
_hidReportDesc[_hidReportDescSize++] = 0x02;
|
||||
}
|
||||
|
||||
// END_COLLECTION
|
||||
_hidReportDesc[_hidReportDescSize++] = 0xc0;
|
||||
|
||||
// END_COLLECTION
|
||||
_hidReportDesc[_hidReportDescSize++] = 0xc0;
|
||||
|
||||
// end of report desc
|
||||
|
||||
_hidReportSize = (USBJ_BUTTON_SIZE / 8) + (_usbJoystickAxisCount * 2);
|
||||
}
|
||||
|
||||
//compare with the old description
|
||||
if (_hidReportDescSize != oldHIDReportDescSize) return true;
|
||||
if (memcmp(_hidReportDesc, oldHIDReportDesc, _hidReportDescSize) != 0) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
extern "C" struct usbReport_t usbReportDesc()
|
||||
{
|
||||
usbReport_t res = { _hidReportDesc, _hidReportDescSize };
|
||||
return res;
|
||||
}
|
||||
|
||||
void usbClassicStateUpdate()
|
||||
{
|
||||
memset(_hidReport, 0, MAX_HID_REPORT);
|
||||
|
||||
//buttons
|
||||
_hidReport[0] = 0;
|
||||
_hidReport[1] = 0;
|
||||
_hidReport[2] = 0;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ( channelOutputs[i+8] > 0 ) {
|
||||
_hidReport[0] |= (1 << i);
|
||||
}
|
||||
if ( channelOutputs[i+16] > 0 ) {
|
||||
_hidReport[1] |= (1 << i);
|
||||
}
|
||||
if ( channelOutputs[i+24] > 0 ) {
|
||||
_hidReport[2] |= (1 << i);
|
||||
}
|
||||
}
|
||||
|
||||
//analog values
|
||||
//uint8_t * p = HID_Buffer + 1;
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
|
||||
int16_t value = channelOutputs[i] + 1024;
|
||||
if ( value > 2047 ) value = 2047;
|
||||
else if ( value < 0 ) value = 0;
|
||||
_hidReport[i*2 +3] = static_cast<uint8_t>(value & 0xFF);
|
||||
_hidReport[i*2 +4] = static_cast<uint8_t>((value >> 8) & 0x07);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void setBtnBits(uint8_t ix, uint8_t value, uint8_t size)
|
||||
{
|
||||
for(uint8_t i = 0; i < size; i++) {
|
||||
uint8_t bitix = ix + i;
|
||||
if(bitix >= USBJ_BUTTON_SIZE) break;
|
||||
|
||||
if(value & (1 << i)) {
|
||||
_buttonState[(bitix / 8)] |= 1 << (bitix % 8);
|
||||
}
|
||||
else {
|
||||
_buttonState[(bitix / 8)] &= ~(1 << (bitix % 8));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void toggleBtnBit(uint8_t bitix)
|
||||
{
|
||||
if(bitix >= USBJ_BUTTON_SIZE) return;
|
||||
_buttonState[(bitix / 8)] ^= 1 << (bitix % 8);
|
||||
}
|
||||
|
||||
#define g_usbTmr10ms (*(uint8_t*)&g_tmr10ms)
|
||||
#define BTNPUSH_TIME 20 /* x10ms */
|
||||
|
||||
static int16_t circularCutoutValue(uint8_t chix)
|
||||
{
|
||||
int32_t value = channelOutputs[chix];
|
||||
uint8_t chpair = 0xff;
|
||||
const int32_t limit = 1048576; /* 1024^2 */
|
||||
|
||||
if(_usbJoystickCircularCut == USBJ_CC_XYZrX) {
|
||||
if(chix == _usbJoystickAxisPairs[0][0]) chpair = _usbJoystickAxisPairs[0][1];
|
||||
else if(chix == _usbJoystickAxisPairs[0][1]) chpair = _usbJoystickAxisPairs[0][0];
|
||||
else if(chix == _usbJoystickAxisPairs[1][0]) chpair = _usbJoystickAxisPairs[1][1];
|
||||
else if(chix == _usbJoystickAxisPairs[1][1]) chpair = _usbJoystickAxisPairs[1][0];
|
||||
}
|
||||
else if(_usbJoystickCircularCut == USBJ_CC_XYrXrZ) {
|
||||
if(chix == _usbJoystickAxisPairs[0][0]) chpair = _usbJoystickAxisPairs[0][1];
|
||||
else if(chix == _usbJoystickAxisPairs[0][1]) chpair = _usbJoystickAxisPairs[0][0];
|
||||
else if(chix == _usbJoystickAxisPairs[2][0]) chpair = _usbJoystickAxisPairs[2][1];
|
||||
else if(chix == _usbJoystickAxisPairs[2][1]) chpair = _usbJoystickAxisPairs[2][0];
|
||||
}
|
||||
|
||||
if(chpair != 0xff) {
|
||||
int32_t pval = channelOutputs[chpair];
|
||||
int32_t sum = ((value*value) + (pval*pval));
|
||||
if(sum > limit) {
|
||||
double ratio = sqrt((double)limit / (double)sum);
|
||||
value *= ratio;
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void usbStateUpdate()
|
||||
{
|
||||
const uint8_t button_ix = 0;
|
||||
const uint8_t axis_ix = button_ix + (USBJ_BUTTON_SIZE >> 3);
|
||||
|
||||
memset(_hidReport, 0, MAX_HID_REPORT);
|
||||
|
||||
uint8_t chix = 0;
|
||||
|
||||
int16_t value = 0;
|
||||
|
||||
uint8_t swpos = 0;
|
||||
uint8_t btnval = 0;
|
||||
|
||||
for (uint8_t i = 0; i < _usbJoystickButtonCount; i++) {
|
||||
chix = _usbJoystickButtonChannels[i];
|
||||
|
||||
value = channelOutputs[chix] + 1024;
|
||||
if ( value > 2047 ) value = 2047;
|
||||
else if ( value < 0 ) value = 0;
|
||||
|
||||
if (_usbJoystickCh[chix].inversion) value = 2047 - value;
|
||||
|
||||
swpos = _usbJoystickCh[chix].switch_npos + 1;
|
||||
|
||||
// Quantization of the values
|
||||
if ((_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_NORMAL)
|
||||
|| (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_ON_PULSE)) {
|
||||
|
||||
if (swpos == 1) {
|
||||
btnval = (value > 1024);
|
||||
} else {
|
||||
btnval = static_cast<uint16_t>(value) / (2048 / swpos);
|
||||
if (btnval >= swpos) btnval = swpos - 1;
|
||||
}
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_SW_EMU) {
|
||||
btnval = (value > 1024);
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_DELTA) {
|
||||
btnval = (value >> 6);
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_COMPANION) {
|
||||
if (swpos == 1 || swpos == 2) {
|
||||
btnval = (value > 1024);
|
||||
} else if (swpos == 3) {
|
||||
btnval = (value < 1024) ? 1 : (value > 1024) ? 2 : 0;
|
||||
} else {
|
||||
btnval = static_cast<uint16_t>(value) / (2048 / swpos);
|
||||
if (btnval >= swpos) btnval = swpos - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Channel Output value changed
|
||||
if ((_usbLastChannelOutput[chix] == 0xffff) || (_usbLastChannelOutput[chix] != btnval)) {
|
||||
|
||||
if ((_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_NORMAL)
|
||||
|| (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_ON_PULSE)) {
|
||||
|
||||
if (swpos == 1) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, btnval, 1);
|
||||
} else {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, 1 << btnval, swpos);
|
||||
}
|
||||
|
||||
// Timer
|
||||
if(_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_ON_PULSE) {
|
||||
_usbChannelTimerActive[chix] = 1;
|
||||
_usbChannelTimer[chix] = g_usbTmr10ms;
|
||||
}
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_SW_EMU) {
|
||||
if ((_usbLastChannelOutput[chix] != 0xffff) && (_usbLastChannelOutput[chix] < btnval)) {
|
||||
toggleBtnBit(_usbJoystickCh[chix].btn_num);
|
||||
}
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_DELTA) {
|
||||
if (_usbLastChannelOutput[chix] != 0xffff) {
|
||||
if (_usbLastChannelOutput[chix] < btnval) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, 2, 2);
|
||||
}
|
||||
else if (_usbLastChannelOutput[chix] > btnval) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, 1, 2);
|
||||
}
|
||||
_usbChannelTimerActive[chix] = 1;
|
||||
_usbChannelTimer[chix] = g_usbTmr10ms;
|
||||
}
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_COMPANION) {
|
||||
if (swpos == 1 || swpos == 2) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, btnval, 1);
|
||||
} else if (swpos == 3) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, btnval, 2);
|
||||
} else {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, 1 << btnval, swpos);
|
||||
}
|
||||
}
|
||||
|
||||
_usbLastChannelOutput[chix] = btnval;
|
||||
}
|
||||
|
||||
// Timer check
|
||||
if((_usbChannelTimerActive[chix]) && (((uint8_t)(g_usbTmr10ms - _usbChannelTimer[chix]) >= BTNPUSH_TIME))) {
|
||||
_usbChannelTimerActive[chix] = 0;
|
||||
|
||||
if(_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_ON_PULSE) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, 0, swpos);
|
||||
}
|
||||
else if (_usbJoystickCh[chix].param == USBJOYS_BTN_MODE_DELTA) {
|
||||
setBtnBits(_usbJoystickCh[chix].btn_num, 0, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(_hidReport + button_ix, _buttonState, (USBJ_BUTTON_SIZE >> 3));
|
||||
|
||||
for (uint8_t i = 0; i < _usbJoystickAxisCount; i++) {
|
||||
chix = _usbJoystickAxisChannels[i];
|
||||
|
||||
value = circularCutoutValue(chix) + 1024;
|
||||
if ( value > 2047 ) value = 2047;
|
||||
else if ( value < 0 ) value = 0;
|
||||
|
||||
if (_usbJoystickCh[chix].inversion) value = 2047 - value;
|
||||
|
||||
_hidReport[i*2 + axis_ix] = static_cast<uint8_t>(value & 0xFF);
|
||||
_hidReport[i*2 + axis_ix+1] = static_cast<uint8_t>((value >> 8) & 0x07);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t usbReportSize()
|
||||
{
|
||||
return _hidReportSize;
|
||||
}
|
||||
|
||||
struct usbReport_t usbReport()
|
||||
{
|
||||
if (!usbJoystickExtMode()) {
|
||||
// Classic USB Joystick report
|
||||
usbClassicStateUpdate();
|
||||
} else {
|
||||
usbStateUpdate();
|
||||
}
|
||||
|
||||
usbReport_t res = { _hidReport, _hidReportSize };
|
||||
return res;
|
||||
}
|
||||
|
||||
void onUSBJoystickModelChanged()
|
||||
{
|
||||
if (!usbJoystickActive()) return;
|
||||
|
||||
if (setupUSBJoystick()) {
|
||||
#if defined(STM32) && !defined(SIMU)
|
||||
usbJoystickRestart();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int isUSBAxisCollision(uint8_t chIdx)
|
||||
{
|
||||
USBJoystickChData * cch = usbJChAddress(chIdx);
|
||||
|
||||
// non axis
|
||||
if (cch->mode != USBJOYS_CH_AXIS) return false;
|
||||
|
||||
// non-unique axis check
|
||||
if (_usbJoystickUniqueAxis[cch->param] == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// collision check
|
||||
for (int i = 0; i < USBJ_MAX_JOYSTICK_CHANNELS; i++) {
|
||||
if (i == chIdx) continue;
|
||||
|
||||
USBJoystickChData * och = usbJChAddress(i);
|
||||
|
||||
if (cch->mode != och->mode) continue;
|
||||
if (cch->param == och->param) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int isUSBSimCollision(uint8_t chIdx)
|
||||
{
|
||||
USBJoystickChData * cch = usbJChAddress(chIdx);
|
||||
|
||||
// non axis
|
||||
if (cch->mode != USBJOYS_CH_SIM) return false;
|
||||
|
||||
// non-unique axis check
|
||||
if (_usbJoystickUniqueSims[cch->param] == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// collision check
|
||||
for (int i = 0; i < USBJ_MAX_JOYSTICK_CHANNELS; i++) {
|
||||
if (i == chIdx) continue;
|
||||
|
||||
USBJoystickChData * och = usbJChAddress(i);
|
||||
|
||||
if (cch->mode != och->mode) continue;
|
||||
if (cch->param == och->param) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int isUSBBtnNumCollision(uint8_t chIdx)
|
||||
{
|
||||
USBJoystickChData * cch = usbJChAddress(chIdx);
|
||||
|
||||
// non button
|
||||
if (cch->mode != USBJOYS_CH_BUTTON) return false;
|
||||
|
||||
// collision check
|
||||
uint8_t cfirst = cch->btn_num;
|
||||
uint8_t clast = cch->lastBtnNum();
|
||||
for (int i = 0; i < USBJ_MAX_JOYSTICK_CHANNELS; i++) {
|
||||
if (i == chIdx) continue;
|
||||
|
||||
USBJoystickChData * och = usbJChAddress(i);
|
||||
|
||||
if (och->mode != USBJOYS_CH_BUTTON) continue;
|
||||
|
||||
uint8_t ofirst = och->btn_num;
|
||||
uint8_t olast = och->lastBtnNum();
|
||||
|
||||
// overlap
|
||||
if ((cfirst <= olast) && (ofirst <= clast)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _USB_JOYSTICK_H_
|
||||
#define _USB_JOYSTICK_H_
|
||||
|
||||
#include "storage/yaml/yaml_defs.h"
|
||||
|
||||
enum USBJoystickIfMode
|
||||
{
|
||||
USBJOYS_JOYSTICK,
|
||||
USBJOYS_GAMEPAD,
|
||||
USBJOYS_MULTIAXIS,
|
||||
USBJOYS_LAST SKIP = USBJOYS_MULTIAXIS
|
||||
};
|
||||
|
||||
enum USBJoystickCh
|
||||
{
|
||||
USBJOYS_CH_NONE,
|
||||
USBJOYS_CH_BUTTON,
|
||||
USBJOYS_CH_AXIS,
|
||||
USBJOYS_CH_SIM,
|
||||
USBJOYS_CH_LAST SKIP = USBJOYS_CH_SIM
|
||||
};
|
||||
|
||||
enum USBJoystickBtnMode
|
||||
{
|
||||
USBJOYS_BTN_MODE_NORMAL,
|
||||
USBJOYS_BTN_MODE_ON_PULSE,
|
||||
USBJOYS_BTN_MODE_SW_EMU,
|
||||
USBJOYS_BTN_MODE_DELTA,
|
||||
USBJOYS_BTN_MODE_COMPANION,
|
||||
USBJOYS_BTN_MODE_LAST SKIP = USBJOYS_BTN_MODE_COMPANION
|
||||
};
|
||||
|
||||
enum USBJoystickAxis
|
||||
{
|
||||
USBJOYS_AXIS_X,
|
||||
USBJOYS_AXIS_Y,
|
||||
USBJOYS_AXIS_Z,
|
||||
USBJOYS_AXIS_RX,
|
||||
USBJOYS_AXIS_RY,
|
||||
USBJOYS_AXIS_RZ,
|
||||
USBJOYS_AXIS_SLIDER,
|
||||
USBJOYS_AXIS_DIAL,
|
||||
USBJOYS_AXIS_WHEEL,
|
||||
USBJOYS_AXIS_LAST SKIP = USBJOYS_AXIS_WHEEL
|
||||
};
|
||||
|
||||
enum USBJoystickSim
|
||||
{
|
||||
USBJOYS_SIM_AILERON,
|
||||
USBJOYS_SIM_ELEVATOR,
|
||||
USBJOYS_SIM_RUDDER,
|
||||
USBJOYS_SIM_THROTTLE,
|
||||
USBJOYS_SIM_LAST SKIP = USBJOYS_SIM_THROTTLE
|
||||
};
|
||||
|
||||
#define USBJ_BUTTON_SIZE 32
|
||||
#define USBJ_MAX_JOYSTICK_CHANNELS 26
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
struct usbReport_t {
|
||||
uint8_t * ptr;
|
||||
uint8_t size;
|
||||
};
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
int usbJoystickExtMode();
|
||||
int usbJoystickActive();
|
||||
int usbJoystickSettingsChanged();
|
||||
|
||||
// Initializes the data based on the model settings
|
||||
// Return value (true = description changed, false = desc. update not needed)
|
||||
int setupUSBJoystick();
|
||||
|
||||
void onUSBJoystickModelChanged();
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
struct usbReport_t usbReportDesc();
|
||||
uint8_t usbReportSize();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
struct usbReport_t usbReport();
|
||||
|
||||
int isUSBAxisCollision(uint8_t chIdx);
|
||||
int isUSBSimCollision(uint8_t chIdx);
|
||||
int isUSBBtnNumCollision(uint8_t chIdx);
|
||||
|
||||
#endif // _USB_JOYSTICK_H_
|
||||
Reference in New Issue
Block a user