Files
edgetx-gx12/companion/src/simulation/simulatordialog.cpp
T

759 lines
22 KiB
C++

/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "simulatordialog.h"
#include "appdata.h"
#include "lcdwidget.h"
#include <iostream>
#include "helpers.h"
#include "simulatorinterface.h"
#include "virtualjoystickwidget.h"
int SimulatorDialog::screenshotIdx = 0;
SimulatorDialog * traceCallbackInstance = 0;
void traceCb(const char * text)
{
// divert C callback into simulator instance
if (traceCallbackInstance) {
traceCallbackInstance->traceCallback(text);
}
}
SimulatorDialog::SimulatorDialog(QWidget * parent, SimulatorInterface *simulator, unsigned int flags):
QDialog(parent),
flags(flags),
timer(NULL),
lightOn(false),
simulator(simulator),
radioProfileId(g.id()),
lastPhase(-1),
beepVal(0),
TelemetrySimu(0),
TrainerSimu(0),
DebugOut(0),
buttonPressed(0),
trimPressed(TRIM_NONE),
middleButtonPressed(false)
{
setWindowFlags(Qt::Window);
grabKeyboard();
new QShortcut(QKeySequence(Qt::Key_F1), this, SLOT(showHelp()));
new QShortcut(QKeySequence(Qt::Key_F4), this, SLOT(openTelemetrySimulator()));
new QShortcut(QKeySequence(Qt::Key_F5), this, SLOT(openTrainerSimulator()));
new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(openDebugOutput()));
new QShortcut(QKeySequence(Qt::Key_F7), this, SLOT(luaReload()));
keymapHelp.append(keymapHelp_t(tr("F1"), tr("Show Help/Keymap")));
keymapHelp.append(keymapHelp_t(tr("F4"), tr("Open Telemetry Simulator")));
keymapHelp.append(keymapHelp_t(tr("F5"), tr("Open Trainer Simulator")));
keymapHelp.append(keymapHelp_t(tr("F6"), tr("Open Debug Output")));
keymapHelp.append(keymapHelp_t(tr("F7"), tr("Reload Lua Scripts")));
traceCallbackInstance = this;
}
SimulatorDialog::~SimulatorDialog()
{
traceCallbackInstance = 0;
delete timer;
delete simulator;
}
void SimulatorDialog::closeEvent(QCloseEvent *)
{
simulator->stop();
timer->stop();
g.profile[radioProfileId].simuWinGeo(saveGeometry());
}
void SimulatorDialog::showEvent(QShowEvent * event)
{
static bool firstShow = true;
if (firstShow) {
restoreGeometry(g.profile[radioProfileId].simuWinGeo());
if (flags & SIMULATOR_FLAGS_STICK_MODE_LEFT || ((flags & SIMULATOR_FLAGS_STANDALONE) && (g.profile[radioProfileId].defaultMode() & 1))) {
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true);
vJoyLeft->setStickY(1);
}
else {
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true);
vJoyRight->setStickY(1);
}
firstShow = false;
}
}
void SimulatorDialog::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::MidButton)
middleButtonPressed = true;
else
event->ignore();
}
void SimulatorDialog::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::MidButton)
middleButtonPressed = false;
else
event->ignore();
}
void SimulatorDialog::wheelEvent(QWheelEvent *event)
{
if (event->angleDelta().isNull())
return;
QPoint numSteps = event->angleDelta() / 8 / 15 * -1; // one step per 15deg
simulator->wheelEvent(numSteps.y());
}
void SimulatorDialog::traceCallback(const char * text)
{
// this function is called from other threads
traceMutex.lock();
// limit the size of list
if (traceList.size() < 1000) {
traceList.append(QString(text));
}
traceMutex.unlock();
}
void SimulatorDialog::setRadioProfileId(int value)
{
radioProfileId = value;
}
void SimulatorDialog::onTrimPressed(int which)
{
trimPressed = which;
}
void SimulatorDialog::onTrimReleased()
{
trimPressed = TRIM_NONE;
}
void SimulatorDialog::onTrimSliderMoved(int which, int value)
{
simulator->setTrim(which, value);
}
void SimulatorDialog::openTelemetrySimulator()
{
// allow only one instance
if (TelemetrySimu == 0) {
TelemetrySimu = new TelemetrySimulator(this, simulator);
TelemetrySimu->show();
}
else if (!TelemetrySimu->isVisible()) {
TelemetrySimu->show();
}
}
void SimulatorDialog::openTrainerSimulator()
{
// allow only one instance
if (TrainerSimu == 0) {
TrainerSimu = new TrainerSimulator(this, simulator);
TrainerSimu->show();
}
else if (!TrainerSimu->isVisible()) {
TrainerSimu->show();
}
}
void SimulatorDialog::openDebugOutput()
{
// allow only one instance, but install signal handler to catch dialog destruction just in case
if (DebugOut == 0) {
DebugOut = new DebugOutput(this);
QObject::connect(DebugOut, SIGNAL(destroyed()), this, SLOT(onDebugOutputClose()));
DebugOut->traceCallback(traceBuffer);
DebugOut->show();
}
else if (!DebugOut->isVisible()) {
DebugOut->show();
}
}
void SimulatorDialog::luaReload()
{
// force a reload of the lua environment (as if a standalone script were run)
simulator->setLuaStateReloadPermanentScripts();
}
void SimulatorDialog::onDebugOutputClose()
{
DebugOut = 0;
}
void SimulatorDialog::showHelp()
{
QString helpText = tr("Simulator Controls:");
helpText += "<table cellspacing=4 cellpadding=0>";
helpText += tr("<tr><th>Key/Mouse</td><th>Action</td></tr>");
QString keyTemplate = "<tr><td align='center'><pre>%1</pre></td><td align='center'>%2</td></tr>";
foreach (keymapHelp_t pair, keymapHelp)
helpText += keyTemplate.arg(pair.first, pair.second);
helpText += "</table>";
QMessageBox * msgBox = new QMessageBox(this);
msgBox->setAttribute(Qt::WA_DeleteOnClose);
msgBox->setWindowFlags(msgBox->windowFlags() | Qt::WindowStaysOnTopHint);
msgBox->setStandardButtons( QMessageBox::Ok );
msgBox->setWindowTitle(tr("Simulator Help"));
msgBox->setText(helpText);
msgBox->setModal(false);
msgBox->show();
}
void SimulatorDialog::keyPressEvent (QKeyEvent *event)
{
switch (event->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
buttonPressed = Qt::Key_Enter;
break;
case Qt::Key_Escape:
case Qt::Key_Backspace:
case Qt::Key_Delete:
buttonPressed = Qt::Key_Escape;
break;
case Qt::Key_Plus:
case Qt::Key_Equal:
buttonPressed = Qt::Key_Plus;
break;
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Right:
case Qt::Key_Left:
case Qt::Key_Minus:
case Qt::Key_PageDown:
case Qt::Key_PageUp:
case Qt::Key_X:
case Qt::Key_C:
buttonPressed = event->key();
break;
default:
event->ignore();
break;
}
}
void SimulatorDialog::keyReleaseEvent(QKeyEvent * event)
{
switch (event->key()) {
case Qt::Key_Enter:
case Qt::Key_Return:
case Qt::Key_Escape:
case Qt::Key_Backspace:
case Qt::Key_Delete:
case Qt::Key_Plus:
case Qt::Key_Equal:
case Qt::Key_Up:
case Qt::Key_Down:
case Qt::Key_Right:
case Qt::Key_Left:
case Qt::Key_Minus:
case Qt::Key_PageDown:
case Qt::Key_PageUp:
case Qt::Key_X:
case Qt::Key_C:
buttonPressed = 0;
break;
default:
event->ignore();
break;
}
}
template <class T>
void SimulatorDialog::initUi(T * ui)
{
ui->setupUi(this);
windowName = tr("Simulating Radio (%1)").arg(GetCurrentFirmware()->getName());
setWindowTitle(windowName);
lcd = ui->lcd;
lcd->setData(simulator->getLcd(), lcdWidth, lcdHeight, lcdDepth);
tabWidget = ui->tabWidget;
pots = findWidgets<QDial *>(this, "pot%1");
potLabels = findWidgets<QLabel *>(this, "potLabel%1");
potValues = findWidgets<QLabel *>(this, "potValue%1");
sliders = findWidgets<QSlider *>(this, "slider%1");
vJoyLeft = new VirtualJoystickWidget(this, 'L');
ui->leftStickLayout->addWidget(vJoyLeft);
vJoyRight = new VirtualJoystickWidget(this, 'R');
ui->rightStickLayout->addWidget(vJoyRight);
connect(vJoyLeft, SIGNAL(trimButtonPressed(int)), this, SLOT(onTrimPressed(int)));
connect(vJoyLeft, SIGNAL(trimButtonReleased()), this, SLOT(onTrimReleased()));
connect(vJoyLeft, SIGNAL(trimSliderMoved(int,int)), this, SLOT(onTrimSliderMoved(int,int)));
connect(vJoyRight, SIGNAL(trimButtonPressed(int)), this, SLOT(onTrimPressed(int)));
connect(vJoyRight, SIGNAL(trimButtonReleased()), this, SLOT(onTrimReleased()));
connect(vJoyRight, SIGNAL(trimSliderMoved(int,int)), this, SLOT(onTrimSliderMoved(int,int)));
#ifdef JOYSTICKS
if (g.jsSupport()) {
int count=0;
for (int j=0; j<8; j++){
int axe = g.joystick[j].stick_axe();
if (axe>=0 && axe<8) {
jsmap[axe]=j+1;
jscal[axe][0] = g.joystick[j].stick_min();
jscal[axe][1] = g.joystick[j].stick_med();
jscal[axe][2] = g.joystick[j].stick_max();
jscal[axe][3] = g.joystick[j].stick_inv();
count++;
}
}
if (count<3) {
QMessageBox::critical(this, tr("Warning"), tr("Joystick enabled but not configured correctly"));
}
if (g.jsCtrl()!=-1) {
joystick = new Joystick(this);
if (joystick) {
if (joystick->open(g.jsCtrl())) {
int numAxes=std::min(joystick->numAxes,8);
for (int j=0; j<numAxes; j++) {
joystick->sensitivities[j] = 0;
joystick->deadzones[j]=0;
}
//mode 1,3 -> THR on right
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true);
vJoyRight->setStickConstraint(VirtualJoystickWidget::HOLD_X, true);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_Y, true);
vJoyLeft->setStickConstraint(VirtualJoystickWidget::HOLD_X, true);
connect(joystick, SIGNAL(axisValueChanged(int, int)), this, SLOT(onjoystickAxisValueChanged(int, int)));
}
else {
QMessageBox::critical(this, tr("Warning"), tr("Cannot open joystick, joystick disabled"));
}
}
}
}
#endif
setupOutputsDisplay();
setupGVarsDisplay();
setTrims();
if (flags & SIMULATOR_FLAGS_NOTX)
tabWidget->setCurrentIndex(1);
}
QFrame * SimulatorDialog::createLogicalSwitch(QWidget * parent, int switchNo, QVector<QLabel *> & labels)
{
QFrame * swtch = new QFrame(parent);
swtch->setAutoFillBackground(true);
swtch->setFrameShape(QFrame::Panel);
swtch->setFrameShadow(QFrame::Raised);
swtch->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
swtch->setMaximumHeight(18);
QVBoxLayout * layout = new QVBoxLayout(swtch);
layout->setContentsMargins(2, 0, 2, 0);
QFont font;
font.setPointSize(8);
QLabel * label = new QLabel(swtch);
label->setFont(font);
label->setText(RawSwitch(SWITCH_TYPE_VIRTUAL, switchNo+1).toString());
label->setAlignment(Qt::AlignCenter);
label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
labels << label;
layout->addWidget(label);
return swtch;
}
void SimulatorDialog::setupOutputsDisplay()
{
// setup Outputs tab
QWidget * outputsWidget = new QWidget();
QGridLayout * gridLayout = new QGridLayout(outputsWidget);
gridLayout->setHorizontalSpacing(0);
gridLayout->setVerticalSpacing(3);
gridLayout->setContentsMargins(5, 3, 5, 3);
// logical switches area
QWidget * logicalSwitches = new QWidget(outputsWidget);
logicalSwitches->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Maximum);
QGridLayout * logicalSwitchesLayout = new QGridLayout(logicalSwitches);
logicalSwitchesLayout->setHorizontalSpacing(3);
logicalSwitchesLayout->setVerticalSpacing(2);
logicalSwitchesLayout->setContentsMargins(0, 0, 0, 0);
gridLayout->addWidget(logicalSwitches, 0, 0, 1, 1);
// channels area
QScrollArea * scrollArea = new QScrollArea(outputsWidget);
QSizePolicy sp(QSizePolicy::Expanding, QSizePolicy::Preferred);
sp.setHorizontalStretch(0);
sp.setVerticalStretch(0);
scrollArea->setSizePolicy(sp);
scrollArea->setWidgetResizable(true);
QWidget * channelsWidget = new QWidget();
QGridLayout * channelsLayout = new QGridLayout(channelsWidget);
channelsLayout->setHorizontalSpacing(4);
channelsLayout->setVerticalSpacing(3);
channelsLayout->setContentsMargins(0, 0, 0, 3);
scrollArea->setWidget(channelsWidget);
gridLayout->addWidget(scrollArea, 1, 0, 1, 1);
tabWidget->insertTab(1, outputsWidget, QString(tr("Outputs")));
// populate outputs
int outputs = std::min(32, GetCurrentFirmware()->getCapability(Outputs));
int column = 0;
for (int i=0; i<outputs; i++) {
QLabel * label = new QLabel(tabWidget);
label->setText(" " + RawSource(SOURCE_TYPE_CH, i).toString() + " ");
label->setAlignment(Qt::AlignCenter);
label->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
channelsLayout->addWidget(label, 0, column, 1, 1);
QSlider * slider = new QSlider(tabWidget);
slider->setEnabled(false);
slider->setMinimum(-1024);
slider->setMaximum(1024);
slider->setPageStep(128);
slider->setTracking(false);
slider->setOrientation(Qt::Vertical);
slider->setInvertedAppearance(false);
slider->setTickPosition(QSlider::TicksRight);
slider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
QLabel * value = new QLabel(tabWidget);
value->setMinimumSize(QSize(value->fontMetrics().size(Qt::TextSingleLine, "-100.0").width(), 0));
value->setAlignment(Qt::AlignCenter);
value->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
channelValues << value;
channelsLayout->addWidget(value, 1, column, 1, 1);
channelSliders << slider;
channelsLayout->addWidget(slider, 2, column++, 1, 1);
channelsLayout->setAlignment(slider, Qt::AlignHCenter);
}
// populate logical switches
int switches = GetCurrentFirmware()->getCapability(LogicalSwitches);
int rows = switches / (switches > 16 ? 4 : 2);
for (int i=0; i<switches; i++) {
QFrame * swtch = createLogicalSwitch(tabWidget, i, logicalSwitchLabels);
logicalSwitchesLayout->addWidget(swtch, i / rows, i % rows, 1, 1);
}
}
void SimulatorDialog::setupGVarsDisplay()
{
int fmodes = GetCurrentFirmware()->getCapability(FlightModes);
int gvars = GetCurrentFirmware()->getCapability(Gvars);
if (gvars>0) {
// setup GVars tab
QWidget * gvarsWidget = new QWidget();
QGridLayout * gvarsLayout = new QGridLayout(gvarsWidget);
tabWidget->addTab(gvarsWidget, QString(tr("GVars")));
for (int fm=0; fm<fmodes; fm++) {
QLabel * label = new QLabel(tabWidget);
label->setText(QString("FM%1").arg(fm));
label->setAlignment(Qt::AlignCenter);
gvarsLayout->addWidget(label, 0, fm+1);
}
for (int i=0; i<gvars; i++) {
QLabel * label = new QLabel(tabWidget);
label->setText(QString("GV%1").arg(i+1));
label->setAutoFillBackground(true);
if ((i % 2) ==0 ) {
label->setStyleSheet("QLabel { background-color: rgb(220, 220, 220) }");
}
gvarsLayout->addWidget(label, i+1, 0);
for (int fm=0; fm<fmodes; fm++) {
QLabel * value = new QLabel(tabWidget);
value->setAutoFillBackground(true);
value->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
if ((i % 2) ==0 ) {
value->setStyleSheet("QLabel { background-color: rgb(220, 220, 220) }");
}
value->setText("0");
gvarValues << value;
gvarsLayout->addWidget(value, i+1, fm+1);
}
}
}
}
void SimulatorDialog::onButtonPressed(int value)
{
if (value == Qt::Key_Print) {
QString fileName = "";
if (!g.snapToClpbrd()) {
fileName = QString("screenshot-%1.png").arg(++screenshotIdx);
}
lcd->makeScreenshot(fileName);
}
else {
buttonPressed = value;
}
}
void SimulatorDialog::updateDebugOutput()
{
traceMutex.lock();
while (!traceList.isEmpty()) {
QString text = traceList.takeFirst();
traceBuffer.append(text);
// limit the size of traceBuffer
if (traceBuffer.size() > 10*1024) {
traceBuffer.remove(0, 1*1024);
}
if (DebugOut) {
DebugOut->traceCallback(QString(text));
}
}
traceMutex.unlock();
}
void SimulatorDialog::onTimerEvent()
{
static unsigned int lcd_counter = 0;
if (!simulator->timer10ms()) {
QMessageBox::critical(this, "Companion", tr("Firmware %1 error: %2").arg(GetCurrentFirmware()->getName()).arg(simulator->getError()));
timer->stop();
return;
}
getValues();
if (tabWidget->currentIndex()==0) {
bool lightEnable;
if (simulator->lcdChanged(lightEnable)) {
lcd->onLcdChanged(lightEnable);
if (lightOn != lightEnable) {
setLightOn(lightEnable);
lightOn = lightEnable;
}
}
}
// display current flight mode in window title
unsigned int currentPhase = simulator->getPhase();
if (currentPhase != lastPhase) {
lastPhase = currentPhase;
const char * phase_name = simulator->getPhaseName(currentPhase);
if (phase_name && phase_name[0]) {
setWindowTitle(windowName + QString(" - Flight Mode %1").arg(QString(phase_name)));
}
else {
setWindowTitle(windowName + QString(" - Flight Mode %1").arg(simulator->getPhase()));
}
}
if (!(lcd_counter++ % 5)) {
setValues();
setTrims();
centerSticks();
updateBeepButton();
if (beepVal) {
beepVal = 0;
QApplication::beep();
}
}
updateDebugOutput();
}
void SimulatorDialog::startCommon()
{
lastPhase = -1;
numGvars = GetCurrentFirmware()->getCapability(Gvars);
numFlightModes = GetCurrentFirmware()->getCapability(FlightModes);
simulator->setVolumeGain(g.profile[radioProfileId].volumeGain());
}
void SimulatorDialog::setupTimer()
{
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(onTimerEvent()));
timer->start(10);
}
void SimulatorDialog::start(QByteArray & eeprom)
{
startCommon();
simulator->start(eeprom, (flags & SIMULATOR_FLAGS_NOTX) ? false : true);
getValues();
setupTimer();
}
void SimulatorDialog::start(const char * filename)
{
startCommon();
simulator->start(filename);
getValues();
setupTimer();
}
void SimulatorDialog::centerSticks()
{
if (vJoyLeft)
vJoyLeft->centerStick();
if (vJoyRight)
vJoyRight->centerStick();
}
void SimulatorDialog::setTrims()
{
typedef VirtualJoystickWidget VJW;
static Trims lastTrims;
Trims trims;
simulator->getTrims(trims);
if (trims.values[VJW::TRIM_AXIS_L_X] != lastTrims.values[VJW::TRIM_AXIS_L_X])
vJoyLeft->setTrimValue(VJW::TRIM_AXIS_L_X, trims.values[VJW::TRIM_AXIS_L_X]);
if (trims.values[VJW::TRIM_AXIS_L_Y] != lastTrims.values[VJW::TRIM_AXIS_L_Y])
vJoyLeft->setTrimValue(VJW::TRIM_AXIS_L_Y, trims.values[VJW::TRIM_AXIS_L_Y]);
if (trims.values[VJW::TRIM_AXIS_R_Y] != lastTrims.values[VJW::TRIM_AXIS_R_Y])
vJoyRight->setTrimValue(VJW::TRIM_AXIS_R_Y, trims.values[VJW::TRIM_AXIS_R_Y]);
if (trims.values[VJW::TRIM_AXIS_R_X] != lastTrims.values[VJW::TRIM_AXIS_R_X])
vJoyRight->setTrimValue(VJW::TRIM_AXIS_R_X, trims.values[VJW::TRIM_AXIS_R_X]);
if (trims.extended != lastTrims.extended) {
int trimMin = -125, trimMax = +125;
if (trims.extended) {
trimMin = -500;
trimMax = +500;
}
vJoyLeft->setTrimRange(VJW::TRIM_AXIS_L_X, trimMin, trimMax);
vJoyLeft->setTrimRange(VJW::TRIM_AXIS_L_Y, trimMin, trimMax);
vJoyRight->setTrimRange(VJW::TRIM_AXIS_R_Y, trimMin, trimMax);
vJoyRight->setTrimRange(VJW::TRIM_AXIS_R_X, trimMin, trimMax);
}
lastTrims = trims;
}
inline int chVal(int val)
{
return qMin(1024, qMax(-1024, val));
}
void SimulatorDialog::setValues()
{
static const int numOutputs = GetCurrentFirmware()->getCapability(Outputs);
static const int numLogicalSwitches = GetCurrentFirmware()->getCapability(LogicalSwitches);
static TxOutputs prevOutputs;
static unsigned int prevPhase = -1;
TxOutputs outputs;
simulator->getValues(outputs);
Trims trims;
simulator->getTrims(trims);
for (int i=0; i<numOutputs; i++) {
if (i < channelSliders.size()) {
channelSliders[i]->setValue(chVal(outputs.chans[i]));
channelValues[i]->setText(QString("%1").arg((qreal)outputs.chans[i]*100/1024, 0, 'f', 1));
}
}
QString CSWITCH_ON = "QLabel { background-color: #4CC417 }";
QString CSWITCH_OFF = "QLabel { }";
for (int i=0; i<numLogicalSwitches; i++) {
if (prevOutputs.vsw[i] != outputs.vsw[i]) {
// setStyleSheet() is very CPU time consuming, doing it only on the actual
// switch state change brings down CPU usage time (for Taranis simulation) from 40% to 7% (Linux, one core usage)
logicalSwitchLabels[i]->setStyleSheet(outputs.vsw[i] ? CSWITCH_ON : CSWITCH_OFF);
}
}
for (unsigned int gv=0; gv<numGvars; gv++) {
for (unsigned int fm=0; fm<numFlightModes; fm++) {
if (prevPhase != lastPhase || prevOutputs.gvars[fm][gv] != outputs.gvars[fm][gv]) {
// same trick for GVARS, but this has far less effect on CPU usage as setStyleSheet()
gvarValues[gv*numFlightModes+fm]->setText(QString((fm==lastPhase)?"<b>%1</b>":"%1").arg(outputs.gvars[fm][gv]));
}
}
}
if (outputs.beep) {
beepVal = outputs.beep;
}
prevOutputs = outputs;
prevPhase = lastPhase;
}
#ifdef JOYSTICKS
void SimulatorDialog::onjoystickAxisValueChanged(int axis, int value)
{
int stick;
if (axis>=0 && axis<=8) {
stick=jsmap[axis];
int stickval;
if (value>jscal[axis][1]) {
if ((jscal[axis][2]-jscal[axis][1])==0)
return;
stickval=(1024*(value-jscal[axis][1]))/(jscal[axis][2]-jscal[axis][1]);
}
else {
if ((jscal[axis][1]-jscal[axis][0])==0)
return;
stickval=(1024*(value-jscal[axis][1]))/(jscal[axis][1]-jscal[axis][0]);
}
if (jscal[axis][3]==1) {
stickval*=-1;
}
if (stick==1 ) {
vJoyRight->setStickY(-stickval/1024.0);
}
else if (stick==2) {
vJoyRight->setStickX(stickval/1024.0);
}
else if (stick==3) {
vJoyLeft->setStickY(-stickval/1024.0);
}
else if (stick==4) {
vJoyLeft->setStickX(stickval/1024.0);
}
else if (stick >= 5 && stick < 5+pots.count()) {
pots[stick-5]->setValue(stickval);
}
}
}
#endif
#include "simulatordialog9x.cpp"
#include "simulatordialogtaranis.cpp"
#include "simulatordialogflamenco.cpp"
#include "simulatordialoghorus.cpp"