diff --git a/companion/src/comparedialog.cpp b/companion/src/comparedialog.cpp index 5ec3a277b..140d7be52 100644 --- a/companion/src/comparedialog.cpp +++ b/companion/src/comparedialog.cpp @@ -1015,8 +1015,8 @@ void CompareDialog::printSwitches() str.append(""); for (int i=0; igetCapability(LogicalSwitches); i++) { GeneralSettings settings; - QString sw1 = g_model1->customSw[i].toString(*g_model1, settings); - QString sw2 = g_model2->customSw[i].toString(*g_model2, settings); + QString sw1 = g_model1->logicalSw[i].toString(*g_model1, settings); + QString sw2 = g_model2->logicalSw[i].toString(*g_model2, settings); if (!(sw1.isEmpty() && sw2.isEmpty())) { str.append(""); color=getColor1(sw1,sw2); @@ -1059,8 +1059,8 @@ void CompareDialog::printFSwitches() str.append(""); for(int i=0; igetCapability(CustomFunctions); i++) { - if (g_model1->funcSw[i].swtch.type || g_model2->funcSw[i].swtch.type) { - if ((g_model1->funcSw[i].swtch != g_model2->funcSw[i].swtch) || (g_model1->funcSw[i].func!=g_model2->funcSw[i].func) || (g_model1->funcSw[i].adjustMode!=g_model2->funcSw[i].adjustMode) || (g_model1->funcSw[i].param!=g_model2->funcSw[i].param)) { + if (g_model1->customFn[i].swtch.type || g_model2->customFn[i].swtch.type) { + if ((g_model1->customFn[i].swtch != g_model2->customFn[i].swtch) || (g_model1->customFn[i].func!=g_model2->customFn[i].func) || (g_model1->customFn[i].adjustMode!=g_model2->customFn[i].adjustMode) || (g_model1->customFn[i].param!=g_model2->customFn[i].param)) { color1="green"; color2="red"; } else { @@ -1068,18 +1068,18 @@ void CompareDialog::printFSwitches() color2="grey"; } str.append(""); - if (g_model1->funcSw[i].swtch.type) { - str.append(doTC(g_model1->funcSw[i].swtch.toString(),color1)); - str.append(doTC(g_model1->funcSw[i].funcToString(),color1)); - str.append(doTC(g_model1->funcSw[i].paramToString(),color1)); - int index=g_model1->funcSw[i].func; + if (g_model1->customFn[i].swtch.type) { + str.append(doTC(g_model1->customFn[i].swtch.toString(),color1)); + str.append(doTC(g_model1->customFn[i].funcToString(),color1)); + str.append(doTC(g_model1->customFn[i].paramToString(),color1)); + int index=g_model1->customFn[i].func; if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { - str.append(doTC(QString("%1").arg(g_model1->funcSw[i].repeatParam),color1)); + str.append(doTC(QString("%1").arg(g_model1->customFn[i].repeatParam),color1)); } else { str.append(doTC( "---",color1)); } if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) { - str.append(doTC((g_model1->funcSw[i].enabled ? "ON" : "OFF"),color1)); + str.append(doTC((g_model1->customFn[i].enabled ? "ON" : "OFF"),color1)); } else { str.append(doTC( "---",color1)); } @@ -1087,18 +1087,18 @@ void CompareDialog::printFSwitches() str.append(""); } str.append(doTC(tr("SF")+QString("%1").arg(i+1),"",true)); - if (g_model2->funcSw[i].swtch.type) { - str.append(doTC(g_model2->funcSw[i].swtch.toString(),color2)); - str.append(doTC(g_model2->funcSw[i].funcToString(),color2)); - str.append(doTC(g_model2->funcSw[i].paramToString(),color2)); - int index=g_model2->funcSw[i].func; + if (g_model2->customFn[i].swtch.type) { + str.append(doTC(g_model2->customFn[i].swtch.toString(),color2)); + str.append(doTC(g_model2->customFn[i].funcToString(),color2)); + str.append(doTC(g_model2->customFn[i].paramToString(),color2)); + int index=g_model2->customFn[i].func; if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { - str.append(doTC(QString("%1").arg(g_model2->funcSw[i].repeatParam),color2)); + str.append(doTC(QString("%1").arg(g_model2->customFn[i].repeatParam),color2)); } else { str.append(doTC( "---",color2)); } if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) { - str.append(doTC((g_model2->funcSw[i].enabled ? "ON" : "OFF"),color2)); + str.append(doTC((g_model2->customFn[i].enabled ? "ON" : "OFF"),color2)); } else { str.append(doTC( "---",color2)); } diff --git a/companion/src/eeprominterface.cpp b/companion/src/eeprominterface.cpp index 596c6f08b..bcad0c347 100644 --- a/companion/src/eeprominterface.cpp +++ b/companion/src/eeprominterface.cpp @@ -713,15 +713,15 @@ QString LogicalSwitchData::toString(const ModelData & model, const GeneralSettin return result; } -void FuncSwData::clear() +void CustomFunctionData::clear() { - memset(this, 0, sizeof(FuncSwData)); + memset(this, 0, sizeof(CustomFunctionData)); if (!GetCurrentFirmware()->getCapability(SafetyChannelCustomFunction)) { func = FuncTrainer; } } -QString FuncSwData::funcToString() +QString CustomFunctionData::funcToString() { ModelData model; if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) @@ -771,7 +771,7 @@ QString FuncSwData::funcToString() } } -QString FuncSwData::paramToString() +QString CustomFunctionData::paramToString() { QStringList qs; if (func <= FuncInstantTrim) { @@ -842,7 +842,7 @@ QString FuncSwData::paramToString() return ""; } -QString FuncSwData::repeatToString() +QString CustomFunctionData::repeatToString() { if (repeatParam==0) { return QObject::tr("No repeat"); @@ -1159,9 +1159,9 @@ void ModelData::clear() for (int i=0; ifunc = func; } + CustomFunctionData(AssignFunc func=FuncOverrideCH1) { clear(); this->func = func; } RawSwitch swtch; AssignFunc func; int param; @@ -1019,8 +1019,8 @@ class ModelData { ExpoData expoData[C9X_MAX_EXPOS]; CurveData curves[C9X_MAX_CURVES]; - LogicalSwitchData customSw[C9X_NUM_CSW]; - FuncSwData funcSw[C9X_MAX_CUSTOM_FUNCTIONS]; + LogicalSwitchData logicalSw[C9X_NUM_CSW]; + CustomFunctionData customFn[C9X_MAX_CUSTOM_FUNCTIONS]; SwashRingData swashRingData; unsigned int thrTraceSrc; unsigned int modelId; @@ -1289,18 +1289,18 @@ inline void applyStickModeToModel(ModelData &model, unsigned int mode) // virtual switches for (int i=0; igetCapability(VoicesAsNumbers)) { for (int i=0; iaddLayout(repeatLayout, i+1, 4); - fswtchRepeat[i] = new RepeatComboBox(this, model.funcSw[i].repeatParam); + fswtchRepeat[i] = new RepeatComboBox(this, model.customFn[i].repeatParam); repeatLayout->addWidget(fswtchRepeat[i], i+1); connect(fswtchRepeat[i], SIGNAL(modified()), this, SLOT(onChildModified())); @@ -308,12 +308,14 @@ void CustomFunctionsPanel::onChildModified() void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) { + CustomFunctionData & cfn = model.customFn[i]; + unsigned int widgetsMask = 0; if (modified) { - model.funcSw[i].swtch = RawSwitch(fswtchSwtch[i]->itemData(fswtchSwtch[i]->currentIndex()).toInt()); - model.funcSw[i].func = (AssignFunc)fswtchFunc[i]->currentIndex(); - model.funcSw[i].enabled = fswtchEnable[i]->isChecked(); - model.funcSw[i].adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex(); + cfn.swtch = RawSwitch(fswtchSwtch[i]->itemData(fswtchSwtch[i]->currentIndex()).toInt()); + cfn.func = (AssignFunc)fswtchFunc[i]->currentIndex(); + cfn.enabled = fswtchEnable[i]->isChecked(); + cfn.adjustMode = (AssignFunc)fswtchGVmode[i]->currentIndex(); } int index = fswtchFunc[i]->currentIndex(); @@ -325,9 +327,9 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParam[i]->setMinimum(-channelsMax); fswtchParam[i]->setMaximum(channelsMax); if (modified) { - model.funcSw[i].param = fswtchParam[i]->value(); + cfn.param = fswtchParam[i]->value(); } - fswtchParam[i]->setValue(model.funcSw[i].param); + fswtchParam[i]->setValue(cfn.param); widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE; } else if (index==FuncLogs) { @@ -335,15 +337,15 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParam[i]->setMinimum(0); fswtchParam[i]->setMaximum(25.5); fswtchParam[i]->setSingleStep(0.1); - if (modified) model.funcSw[i].param = fswtchParam[i]->value()*10.0; - fswtchParam[i]->setValue(model.funcSw[i].param/10.0); + if (modified) cfn.param = fswtchParam[i]->value()*10.0; + fswtchParam[i]->setValue(cfn.param/10.0); widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; } else if (index>=FuncAdjustGV1 && index<=FuncAdjustGVLast) { - if (modified) model.funcSw[i].adjustMode = fswtchGVmode[i]->currentIndex(); + if (modified) cfn.adjustMode = fswtchGVmode[i]->currentIndex(); widgetsMask |= CUSTOM_FUNCTION_GV_MODE + CUSTOM_FUNCTION_ENABLE; - if (model.funcSw[i].adjustMode==0) { - if (modified) model.funcSw[i].param = fswtchParam[i]->value(); + if (cfn.adjustMode==0) { + if (modified) cfn.param = fswtchParam[i]->value(); fswtchParam[i]->setDecimals(0); fswtchParam[i]->setSingleStep(1); if (IS_ARM(GetEepromInterface()->getBoard())) { @@ -354,32 +356,32 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParam[i]->setMinimum(-125); fswtchParam[i]->setMaximum(125); } - fswtchParam[i]->setValue(model.funcSw[i].param); + fswtchParam[i]->setValue(cfn.param); widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; } else { - if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); - populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param, model.funcSw[i].adjustMode); + if (modified) cfn.param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); + populateFuncParamCB(fswtchParamT[i], model, index, cfn.param, cfn.adjustMode); widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } } else if (index==FuncReset) { - if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param); + if (modified) cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], model, index, cfn.param); widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; } else if (index>=FuncSetTimer1 && index<=FuncSetTimer2) { - if (modified) model.funcSw[i].param = fswtchParam[i]->value(); + if (modified) cfn.param = fswtchParam[i]->value(); fswtchParam[i]->setDecimals(0); fswtchParam[i]->setSingleStep(1); fswtchParam[i]->setMinimum(0); fswtchParam[i]->setMaximum(59*60+59); - fswtchParam[i]->setValue(model.funcSw[i].param); + fswtchParam[i]->setValue(cfn.param); widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM + CUSTOM_FUNCTION_ENABLE; } else if (index==FuncVolume) { - if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); - populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param); + if (modified) cfn.param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); + populateFuncParamCB(fswtchParamT[i], model, index, cfn.param); widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_ENABLE; } else if (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic) { @@ -388,8 +390,8 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchRepeat[i]->update(); } if (index==FuncPlayValue) { - if (modified) model.funcSw[i].param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); - populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param); + if (modified) cfn.param = fswtchParamT[i]->itemData(fswtchParamT[i]->currentIndex()).toInt(); + populateFuncParamCB(fswtchParamT[i], model, index, cfn.param); widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM + CUSTOM_FUNCTION_REPEAT; } else if (index==FuncPlayPrompt || index==FuncPlayBoth) { @@ -408,38 +410,38 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) if (modified) { if (fswtchParamGV[i]->isChecked()) { fswtchParam[i]->setMinimum(1); - model.funcSw[i].param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); + cfn.param = std::min(fswtchParam[i]->value(),5.0)+(fswtchParamGV[i]->isChecked() ? 250 : 0); } else { - model.funcSw[i].param = fswtchParam[i]->value(); + cfn.param = fswtchParam[i]->value(); } } - if (model.funcSw[i].param>250 && (index!=FuncPlayBoth)) { + if (cfn.param>250 && (index!=FuncPlayBoth)) { fswtchParamGV[i]->setChecked(true); - fswtchParam[i]->setValue(model.funcSw[i].param-250); + fswtchParam[i]->setValue(cfn.param-250); fswtchParam[i]->setMaximum(5); } else { fswtchParamGV[i]->setChecked(false); - fswtchParam[i]->setValue(model.funcSw[i].param); + fswtchParam[i]->setValue(cfn.param); } - if (model.funcSw[i].param < 251) + if (cfn.param < 251) widgetsMask |= CUSTOM_FUNCTION_PLAY; } else { widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { - memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm)); + memset(cfn.paramarm, 0, sizeof(cfn.paramarm)); int vml = firmware->getCapability(VoicesMaxLength); if (fswtchParamArmT[i]->currentText() != "----") { widgetsMask |= CUSTOM_FUNCTION_PLAY; for (int j=0; jcurrentText().length(), vml); j++) { - model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j); + cfn.paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j); } } } else { - populateFuncParamArmTCB(fswtchParamArmT[i], model.funcSw[i].paramarm, paramarmList); + populateFuncParamArmTCB(fswtchParamArmT[i], cfn.paramarm, paramarmList); if (fswtchParamArmT[i]->currentText() != "----") { widgetsMask |= CUSTOM_FUNCTION_PLAY; } @@ -449,37 +451,37 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) else if (index==FuncBackgroundMusic) { widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM; if (modified) { - memset(model.funcSw[i].paramarm, 0, sizeof(model.funcSw[i].paramarm)); + memset(cfn.paramarm, 0, sizeof(cfn.paramarm)); int vml=firmware->getCapability(VoicesMaxLength); if (fswtchParamArmT[i]->currentText() != "----") { widgetsMask |= CUSTOM_FUNCTION_PLAY; for (int j=0; jcurrentText().length(),vml); j++) { - model.funcSw[i].paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j); + cfn.paramarm[j] = fswtchParamArmT[i]->currentText().toAscii().at(j); } } } } else if (index==FuncPlaySound) { - if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param); + if (modified) cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], model, index, cfn.param); widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } else if (index==FuncPlayHaptic) { - if (modified) model.funcSw[i].param = (uint8_t)fswtchParamT[i]->currentIndex(); - populateFuncParamCB(fswtchParamT[i], model, index, model.funcSw[i].param); + if (modified) cfn.param = (uint8_t)fswtchParamT[i]->currentIndex(); + populateFuncParamCB(fswtchParamT[i], model, index, cfn.param); widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } } else if (index==FuncBacklight && IS_TARANIS_PLUS(GetEepromInterface()->getBoard())) { - if (modified) model.funcSw[i].param = (uint8_t)fswtchBLcolor[i]->value(); - fswtchBLcolor[i]->setValue(model.funcSw[i].param); + if (modified) cfn.param = (uint8_t)fswtchBLcolor[i]->value(); + fswtchBLcolor[i]->setValue(cfn.param); widgetsMask |= CUSTOM_FUNCTION_BL_COLOR; } else { - if (modified) model.funcSw[i].param = fswtchParam[i]->value(); + if (modified) cfn.param = fswtchParam[i]->value(); fswtchParam[i]->setDecimals(0); fswtchParam[i]->setSingleStep(1); - fswtchParam[i]->setValue(model.funcSw[i].param); + fswtchParam[i]->setValue(cfn.param); if (index <= FuncInstantTrim) { widgetsMask |= CUSTOM_FUNCTION_ENABLE; } @@ -491,7 +493,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM); fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE); if (widgetsMask & CUSTOM_FUNCTION_ENABLE) - fswtchEnable[i]->setChecked(model.funcSw[i].enabled); + fswtchEnable[i]->setChecked(cfn.enabled); else fswtchEnable[i]->setChecked(false); fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT); @@ -507,11 +509,11 @@ void CustomFunctionsPanel::update() lock = true; for (int i=0; igetCapability(CustomFunctions); i++) { if (!initialized) { - populateSwitchCB(fswtchSwtch[i], model.funcSw[i].swtch, generalSettings, CustomFunctionsContext); - populateFuncCB(fswtchFunc[i], model.funcSw[i].func); - populateGVmodeCB(fswtchGVmode[i], model.funcSw[i].adjustMode); - populateFuncParamCB(fswtchParamT[i], model, model.funcSw[i].func, model.funcSw[i].param, model.funcSw[i].adjustMode); - populateFuncParamArmTCB(fswtchParamArmT[i], model.funcSw[i].paramarm, paramarmList); + populateSwitchCB(fswtchSwtch[i], model.customFn[i].swtch, generalSettings, CustomFunctionsContext); + populateFuncCB(fswtchFunc[i], model.customFn[i].func); + populateGVmodeCB(fswtchGVmode[i], model.customFn[i].adjustMode); + populateFuncParamCB(fswtchParamT[i], model, model.customFn[i].func, model.customFn[i].param, model.customFn[i].adjustMode); + populateFuncParamArmTCB(fswtchParamArmT[i], model.customFn[i].paramarm, paramarmList); } refreshCustomFunction(i); } @@ -525,14 +527,14 @@ void CustomFunctionsPanel::fswPaste() const QMimeData *mimeData = clipboard->mimeData(); if (mimeData->hasFormat("application/x-companion-fsw")) { QByteArray fswData = mimeData->data("application/x-companion-fsw"); - FuncSwData *fsw = &model.funcSw[selectedFunction]; - memcpy(fsw, fswData.mid(0, sizeof(FuncSwData)).constData(), sizeof(FuncSwData)); + CustomFunctionData *fsw = &model.customFn[selectedFunction]; + memcpy(fsw, fswData.mid(0, sizeof(CustomFunctionData)).constData(), sizeof(CustomFunctionData)); lock = true; - populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, CustomFunctionsContext); - populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func); - populateGVmodeCB(fswtchGVmode[selectedFunction], model.funcSw[selectedFunction].adjustMode); - populateFuncParamCB(fswtchParamT[selectedFunction], model, model.funcSw[selectedFunction].func, model.funcSw[selectedFunction].param, model.funcSw[selectedFunction].adjustMode); - populateFuncParamArmTCB(fswtchParamArmT[selectedFunction], model.funcSw[selectedFunction].paramarm, paramarmList); + populateSwitchCB(fswtchSwtch[selectedFunction], model.customFn[selectedFunction].swtch, generalSettings, CustomFunctionsContext); + populateFuncCB(fswtchFunc[selectedFunction], model.customFn[selectedFunction].func); + populateGVmodeCB(fswtchGVmode[selectedFunction], model.customFn[selectedFunction].adjustMode); + populateFuncParamCB(fswtchParamT[selectedFunction], model, model.customFn[selectedFunction].func, model.customFn[selectedFunction].param, model.customFn[selectedFunction].adjustMode); + populateFuncParamArmTCB(fswtchParamArmT[selectedFunction], model.customFn[selectedFunction].paramarm, paramarmList); refreshCustomFunction(selectedFunction); lock = false; emit modified(); @@ -541,11 +543,11 @@ void CustomFunctionsPanel::fswPaste() void CustomFunctionsPanel::fswDelete() { - model.funcSw[selectedFunction].clear(); + model.customFn[selectedFunction].clear(); // TODO update switch and func lock = true; - populateSwitchCB(fswtchSwtch[selectedFunction], model.funcSw[selectedFunction].swtch, generalSettings, CustomFunctionsContext); - populateFuncCB(fswtchFunc[selectedFunction], model.funcSw[selectedFunction].func); + populateSwitchCB(fswtchSwtch[selectedFunction], model.customFn[selectedFunction].swtch, generalSettings, CustomFunctionsContext); + populateFuncCB(fswtchFunc[selectedFunction], model.customFn[selectedFunction].func); refreshCustomFunction(selectedFunction); lock = false; emit modified(); @@ -554,7 +556,7 @@ void CustomFunctionsPanel::fswDelete() void CustomFunctionsPanel::fswCopy() { QByteArray fswData; - fswData.append((char*)&model.funcSw[selectedFunction], sizeof(FuncSwData)); + fswData.append((char*)&model.customFn[selectedFunction], sizeof(CustomFunctionData)); QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-companion-fsw", fswData); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); @@ -590,7 +592,7 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) { b->clear(); for (unsigned int i=0; iaddItem(FuncSwData(AssignFunc(i)).funcToString()); + b->addItem(CustomFunctionData(AssignFunc(i)).funcToString()); if (((i>=FuncOverrideCH1 && i<=FuncOverrideCH32) && !firmware->getCapability(SafetyChannelCustomFunction)) || ((i==FuncVolume || i==FuncBackgroundMusic || i==FuncBackgroundMusicPause) && !firmware->getCapability(HasVolume)) || ((i==FuncPlayHaptic) && !firmware->getCapability(Haptic)) || diff --git a/companion/src/modeledit/logicalswitches.cpp b/companion/src/modeledit/logicalswitches.cpp index 0c31be7b4..db620fc3e 100644 --- a/companion/src/modeledit/logicalswitches.cpp +++ b/companion/src/modeledit/logicalswitches.cpp @@ -138,11 +138,11 @@ void LogicalSwitchesPanel::v1Edited(int value) { if (!lock) { int i = sender()->property("index").toInt(); - model.customSw[i].val1 = cswitchSource1[i]->itemData(value).toInt(); - if (model.customSw[i].getFunctionFamily() == LS_FAMILY_VOFS) { - RawSource source = RawSource(model.customSw[i].val1); - RawSourceRange range = source.getRange(model, generalSettings, model.customSw[i].getRangeFlags()); - model.customSw[i].val2 = (cswitchOffset[i]->value() - range.offset) / range.step; + model.logicalSw[i].val1 = cswitchSource1[i]->itemData(value).toInt(); + if (model.logicalSw[i].getFunctionFamily() == LS_FAMILY_VOFS) { + RawSource source = RawSource(model.logicalSw[i].val1); + RawSourceRange range = source.getRange(model, generalSettings, model.logicalSw[i].getRangeFlags()); + model.logicalSw[i].val2 = (cswitchOffset[i]->value() - range.offset) / range.step; setSwitchWidgetVisibility(i); } emit modified(); @@ -153,7 +153,7 @@ void LogicalSwitchesPanel::v2Edited(int value) { if (!lock) { int i = sender()->property("index").toInt(); - model.customSw[i].val2 = cswitchSource2[i]->itemData(value).toInt(); + model.logicalSw[i].val2 = cswitchSource2[i]->itemData(value).toInt(); emit modified(); } } @@ -162,7 +162,7 @@ void LogicalSwitchesPanel::andEdited(int value) { if (!lock) { int index = sender()->property("index").toInt(); - model.customSw[index].andsw = cswitchAnd[index]->itemData(value).toInt(); + model.logicalSw[index].andsw = cswitchAnd[index]->itemData(value).toInt(); emit modified(); } } @@ -171,7 +171,7 @@ void LogicalSwitchesPanel::durationEdited(double duration) { if (!lock) { int index = sender()->property("index").toInt(); - model.customSw[index].duration = (uint8_t)round(duration*10); + model.logicalSw[index].duration = (uint8_t)round(duration*10); emit modified(); } } @@ -180,7 +180,7 @@ void LogicalSwitchesPanel::delayEdited(double delay) { if (!lock) { int index = sender()->property("index").toInt(); - model.customSw[index].delay = (uint8_t)round(delay*10); + model.logicalSw[index].delay = (uint8_t)round(delay*10); emit modified(); } } @@ -190,30 +190,30 @@ void LogicalSwitchesPanel::edited() if (!lock) { lock = true; int i = sender()->property("index").toInt(); - CSFunctionFamily oldFuncFamily = model.customSw[i].getFunctionFamily(); - model.customSw[i].func = csw[i]->itemData(csw[i]->currentIndex()).toInt(); - CSFunctionFamily newFuncFamily = model.customSw[i].getFunctionFamily(); + CSFunctionFamily oldFuncFamily = model.logicalSw[i].getFunctionFamily(); + model.logicalSw[i].func = csw[i]->itemData(csw[i]->currentIndex()).toInt(); + CSFunctionFamily newFuncFamily = model.logicalSw[i].getFunctionFamily(); if (oldFuncFamily != newFuncFamily) { if (newFuncFamily == LS_FAMILY_TIMER) { - model.customSw[i].val1 = -119; - model.customSw[i].val2 = -119; + model.logicalSw[i].val1 = -119; + model.logicalSw[i].val2 = -119; } else if (newFuncFamily == LS_FAMILY_EDGE) { - model.customSw[i].val1 = 0; - model.customSw[i].val2 = -129; - model.customSw[i].val3 = 0; + model.logicalSw[i].val1 = 0; + model.logicalSw[i].val2 = -129; + model.logicalSw[i].val3 = 0; } else if (newFuncFamily == LS_FAMILY_STICKY) { - model.customSw[i].val1 = 0; - model.customSw[i].val2 = 0; - model.customSw[i].delay = 0; + model.logicalSw[i].val1 = 0; + model.logicalSw[i].val2 = 0; + model.logicalSw[i].delay = 0; } else { - model.customSw[i].val1 = 0; - model.customSw[i].val2 = 0; + model.logicalSw[i].val1 = 0; + model.logicalSw[i].val2 = 0; } - model.customSw[i].andsw = 0; + model.logicalSw[i].andsw = 0; setSwitchWidgetVisibility(i); } @@ -223,11 +223,11 @@ void LogicalSwitchesPanel::edited() { case LS_FAMILY_VOFS: { - source = RawSource(model.customSw[i].val1); - RawSourceRange range = source.getRange(model, generalSettings, model.customSw[i].getRangeFlags()); + source = RawSource(model.logicalSw[i].val1); + RawSourceRange range = source.getRange(model, generalSettings, model.logicalSw[i].getRangeFlags()); double value = source.isTimeBased() ? QTimeS(cswitchTOffset[i]->time()).seconds() : cswitchOffset[i]->value(); - model.customSw[i].val2 = round((value-range.offset)/range.step);; - value = model.customSw[i].val2*range.step + range.offset; + model.logicalSw[i].val2 = round((value-range.offset)/range.step);; + value = model.logicalSw[i].val2*range.step + range.offset; if (source.isTimeBased()) cswitchTOffset[i]->setTime(QTimeS(round(value))); else @@ -235,22 +235,22 @@ void LogicalSwitchesPanel::edited() break; } case LS_FAMILY_TIMER: - model.customSw[i].val1 = TimToVal(cswitchValue[i]->value()); - model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value()); - updateTimerParam(cswitchValue[i], model.customSw[i].val1, 0.1); - updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1); + model.logicalSw[i].val1 = TimToVal(cswitchValue[i]->value()); + model.logicalSw[i].val2 = TimToVal(cswitchOffset[i]->value()); + updateTimerParam(cswitchValue[i], model.logicalSw[i].val1, 0.1); + updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.1); break; case LS_FAMILY_EDGE: cswitchOffset2[i]->setSpecialValueText(tr("(no release)")); if (sender() == cswitchOffset[i]) { - model.customSw[i].val2 = TimToVal(cswitchOffset[i]->value()); - updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0); + model.logicalSw[i].val2 = TimToVal(cswitchOffset[i]->value()); + updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.0); } else { - model.customSw[i].val3 = TimToVal(cswitchOffset2[i]->value()) - model.customSw[i].val2; + model.logicalSw[i].val3 = TimToVal(cswitchOffset2[i]->value()) - model.logicalSw[i].val2; } - updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1); - if (model.customSw[i].val3 == 0) { + updateTimerParam(cswitchOffset2[i], model.logicalSw[i].val2+model.logicalSw[i].val3, cswitchOffset[i]->value()-0.1); + if (model.logicalSw[i].val3 == 0) { cswitchOffset2[i]->setSuffix("(infinite)"); } else { @@ -294,10 +294,10 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i) lock = true; unsigned int mask = DELAY_ENABLED; - RawSource source = RawSource(model.customSw[i].val1); - RawSourceRange range = source.getRange(model, generalSettings, model.customSw[i].getRangeFlags()); + RawSource source = RawSource(model.logicalSw[i].val1); + RawSourceRange range = source.getRange(model, generalSettings, model.logicalSw[i].getRangeFlags()); - switch (model.customSw[i].getFunctionFamily()) + switch (model.logicalSw[i].getFunctionFamily()) { case LS_FAMILY_VOFS: mask |= SOURCE1_VISIBLE; @@ -307,7 +307,7 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i) if (source.isTimeBased()) { mask |= VALUE_TO_VISIBLE; int maxTime = round(range.max); - int value = round(range.step*model.customSw[i].val2 + range.offset); + int value = round(range.step*model.logicalSw[i].val2 + range.offset); cswitchTOffset[i]->setMaximumTime(QTimeS(maxTime)); cswitchTOffset[i]->setDisplayFormat((maxTime>=3600)?"hh:mm:ss":"mm:ss"); cswitchTOffset[i]->setTime(QTimeS(value)); @@ -320,24 +320,24 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i) cswitchOffset[i]->setSuffix(" " + range.unit); cswitchOffset[i]->setMinimum(range.min); cswitchOffset[i]->setMaximum(range.max); - cswitchOffset[i]->setValue(range.step*(model.customSw[i].val2/* TODO+source.getRawOffset(model)*/)+range.offset); + cswitchOffset[i]->setValue(range.step*(model.logicalSw[i].val2/* TODO+source.getRawOffset(model)*/)+range.offset); } break; case LS_FAMILY_STICKY: // no break case LS_FAMILY_VBOOL: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; - populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext); - populateSwitchCB(cswitchSource2[i], RawSwitch(model.customSw[i].val2), generalSettings, LogicalSwitchesContext); + populateSwitchCB(cswitchSource1[i], RawSwitch(model.logicalSw[i].val1), generalSettings, LogicalSwitchesContext); + populateSwitchCB(cswitchSource2[i], RawSwitch(model.logicalSw[i].val2), generalSettings, LogicalSwitchesContext); break; case LS_FAMILY_EDGE: mask |= SOURCE1_VISIBLE | VALUE2_VISIBLE | VALUE3_VISIBLE; mask &= ~DELAY_ENABLED; - populateSwitchCB(cswitchSource1[i], RawSwitch(model.customSw[i].val1), generalSettings, LogicalSwitchesContext); - updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.0); - updateTimerParam(cswitchOffset2[i], model.customSw[i].val2+model.customSw[i].val3, cswitchOffset[i]->value()-0.1); + populateSwitchCB(cswitchSource1[i], RawSwitch(model.logicalSw[i].val1), generalSettings, LogicalSwitchesContext); + updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.0); + updateTimerParam(cswitchOffset2[i], model.logicalSw[i].val2+model.logicalSw[i].val3, cswitchOffset[i]->value()-0.1); cswitchOffset2[i]->setSpecialValueText(tr("(no release)")); - if (model.customSw[i].val3 == 0) { + if (model.logicalSw[i].val3 == 0) { cswitchOffset2[i]->setSuffix(tr("(infinite)")); } else { @@ -346,13 +346,13 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i) break; case LS_FAMILY_VCOMP: mask |= SOURCE1_VISIBLE | SOURCE2_VISIBLE; - populateSourceCB(cswitchSource1[i], RawSource(model.customSw[i].val1), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0)); - populateSourceCB(cswitchSource2[i], RawSource(model.customSw[i].val2), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0)); + populateSourceCB(cswitchSource1[i], RawSource(model.logicalSw[i].val1), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0)); + populateSourceCB(cswitchSource2[i], RawSource(model.logicalSw[i].val2), model, POPULATE_SOURCES | POPULATE_SCRIPT_OUTPUTS | POPULATE_VIRTUAL_INPUTS | POPULATE_TRIMS | POPULATE_SWITCHES | POPULATE_TELEMETRY | (firmware->getCapability(GvarsInCS) ? POPULATE_GVARS : 0)); break; case LS_FAMILY_TIMER: mask |= VALUE1_VISIBLE | VALUE2_VISIBLE; - updateTimerParam(cswitchValue[i], model.customSw[i].val1, 0.1); - updateTimerParam(cswitchOffset[i], model.customSw[i].val2, 0.1); + updateTimerParam(cswitchValue[i], model.logicalSw[i].val1, 0.1); + updateTimerParam(cswitchOffset[i], model.logicalSw[i].val2, 0.1); break; } @@ -364,8 +364,8 @@ void LogicalSwitchesPanel::setSwitchWidgetVisibility(int i) cswitchTOffset[i]->setVisible(mask & VALUE_TO_VISIBLE); if (firmware->getCapability(LogicalSwitchesExt)) { cswitchDelay[i]->setEnabled(mask & DELAY_ENABLED); - cswitchDuration[i]->setValue(model.customSw[i].duration/10.0); - cswitchDelay[i]->setValue(model.customSw[i].delay/10.0); + cswitchDuration[i]->setValue(model.logicalSw[i].duration/10.0); + cswitchDelay[i]->setValue(model.logicalSw[i].delay/10.0); } lock = false; } @@ -445,11 +445,11 @@ void LogicalSwitchesPanel::populateAndSwitchCB(QComboBox *b, const RawSwitch & v void LogicalSwitchesPanel::updateLine(int i) { lock = true; - populateCSWCB(csw[i], model.customSw[i].func); + populateCSWCB(csw[i], model.logicalSw[i].func); lock = true; setSwitchWidgetVisibility(i); lock = true; - populateAndSwitchCB(cswitchAnd[i], RawSwitch(model.customSw[i].andsw)); + populateAndSwitchCB(cswitchAnd[i], RawSwitch(model.logicalSw[i].andsw)); lock = false; } @@ -466,7 +466,7 @@ void LogicalSwitchesPanel::cswPaste() const QMimeData *mimeData = clipboard->mimeData(); if (mimeData->hasFormat("application/x-companion-csw")) { QByteArray cswData = mimeData->data("application/x-companion-csw"); - LogicalSwitchData *csw = &model.customSw[selectedSwitch]; + LogicalSwitchData *csw = &model.logicalSw[selectedSwitch]; memcpy(csw, cswData.mid(0, sizeof(LogicalSwitchData)).constData(), sizeof(LogicalSwitchData)); emit modified(); updateLine(selectedSwitch); @@ -475,7 +475,7 @@ void LogicalSwitchesPanel::cswPaste() void LogicalSwitchesPanel::cswDelete() { - model.customSw[selectedSwitch].clear(); + model.logicalSw[selectedSwitch].clear(); emit modified(); updateLine(selectedSwitch); } @@ -483,7 +483,7 @@ void LogicalSwitchesPanel::cswDelete() void LogicalSwitchesPanel::cswCopy() { QByteArray cswData; - cswData.append((char*)&model.customSw[selectedSwitch],sizeof(LogicalSwitchData)); + cswData.append((char*)&model.logicalSw[selectedSwitch],sizeof(LogicalSwitchData)); QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-companion-csw", cswData); QApplication::clipboard()->setMimeData(mimeData,QClipboard::Clipboard); diff --git a/companion/src/modeledit/templates.cpp b/companion/src/modeledit/templates.cpp index de4175349..30b383ff6 100644 --- a/companion/src/modeledit/templates.cpp +++ b/companion/src/modeledit/templates.cpp @@ -60,9 +60,9 @@ Templates::~Templates() void Templates::setSwitch(unsigned int idx, unsigned int func, int v1, int v2) { - g_model.customSw[idx-1].func = func; - g_model.customSw[idx-1].val1 = v1; - g_model.customSw[idx-1].val2 = v2; + g_model.logicalSw[idx-1].func = func; + g_model.logicalSw[idx-1].val1 = v1; + g_model.logicalSw[idx-1].val2 = v2; } void Templates::onDoubleClicked(QModelIndex index) diff --git a/companion/src/printdialog.cpp b/companion/src/printdialog.cpp index 15b208b88..02b94c223 100644 --- a/companion/src/printdialog.cpp +++ b/companion/src/printdialog.cpp @@ -577,10 +577,10 @@ void PrintDialog::printSwitches() str.append("
     
"); for (int i=0; igetCapability(LogicalSwitches); i++) { - if (g_model->customSw[i].func) { + if (g_model->logicalSw[i].func) { str.append(""); str.append("").arg(i+1)); - QString tstr = g_model->customSw[i].toString(*g_model, *g_eeGeneral); + QString tstr = g_model->logicalSw[i].toString(*g_model, *g_eeGeneral); str.append(doTL(tstr,"green")); str.append(""); sc++; @@ -630,21 +630,21 @@ void PrintDialog::printFSwitches() str.append(doTL(tr("Enabled"), "", true)); str.append(""); for(int i=0; igetCapability(CustomFunctions); i++) { - if (g_model->funcSw[i].swtch.type!=SWITCH_TYPE_NONE) { + if (g_model->customFn[i].swtch.type!=SWITCH_TYPE_NONE) { str.append(""); str.append(doTL(tr("SF%1").arg(i+1),"", true)); - str.append(doTL(g_model->funcSw[i].swtch.toString(),"green")); - str.append(doTL(g_model->funcSw[i].funcToString(),"green")); - str.append(doTL(g_model->funcSw[i].paramToString(),"green")); - int index=g_model->funcSw[i].func; - if ((g_model->funcSw[i].repeatParam>0) && + str.append(doTL(g_model->customFn[i].swtch.toString(),"green")); + str.append(doTL(g_model->customFn[i].funcToString(),"green")); + str.append(doTL(g_model->customFn[i].paramToString(),"green")); + int index=g_model->customFn[i].func; + if ((g_model->customFn[i].repeatParam>0) && (index==FuncPlaySound || index==FuncPlayHaptic || index==FuncPlayValue || index==FuncPlayPrompt || index==FuncPlayBoth || index==FuncBackgroundMusic)) { - str.append(doTL(QString("%1").arg(g_model->funcSw[i].repeatParam),"green")); + str.append(doTL(QString("%1").arg(g_model->customFn[i].repeatParam),"green")); } else { str.append(doTL( " ","green")); } if ((index<=FuncInstantTrim) || (index>FuncBackgroundMusicPause)) { - str.append(doTL((g_model->funcSw[i].enabled ? "ON" : "OFF"),"green")); + str.append(doTL((g_model->customFn[i].enabled ? "ON" : "OFF"),"green")); } else { str.append(doTL( "---","green")); } diff --git a/companion/src/wizarddata.cpp b/companion/src/wizarddata.cpp index 62a9f1c7c..b9764892d 100644 --- a/companion/src/wizarddata.cpp +++ b/companion/src/wizarddata.cpp @@ -110,11 +110,11 @@ WizMix::operator ModelData() // Add the Throttle Cut option if( options[THROTTLE_CUT_OPTION] && throttleChannel >=0 ){ - model.funcSw[switchIndex].swtch.type = SWITCH_TYPE_SWITCH; - model.funcSw[switchIndex].swtch.index = isTaranis ? SWITCH_SF0 : SWITCH_THR; - model.funcSw[switchIndex].enabled = 1; - model.funcSw[switchIndex].func = (AssignFunc)throttleChannel; - model.funcSw[switchIndex].param = -100; + model.customFn[switchIndex].swtch.type = SWITCH_TYPE_SWITCH; + model.customFn[switchIndex].swtch.index = isTaranis ? SWITCH_SF0 : SWITCH_THR; + model.customFn[switchIndex].enabled = 1; + model.customFn[switchIndex].func = (AssignFunc)throttleChannel; + model.customFn[switchIndex].param = -100; } // Add the Flight Timer option diff --git a/radio/src/Makefile b/radio/src/Makefile index 677365c4a..8ae616996 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -820,7 +820,7 @@ else TTS_SRC = $(shell sh -c "if test -f $(STD_TTS_SRC); then echo $(STD_TTS_SRC); else echo translations/tts_en.cpp; fi") endif -CPPSRC += opentx.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC) +CPPSRC += opentx.cpp functions.cpp strhelpers.cpp $(PULSESSRC) switches.cpp curves.cpp mixer.cpp stamp.cpp gui/menus.cpp gui/menu_model.cpp gui/menu_general.cpp gui/view_main.cpp gui/view_statistics.cpp $(EEPROMSRC) $(LCDSRC) keys.cpp maths.cpp translations.cpp fonts.cpp $(TTS_SRC) # Debugging format. # Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. diff --git a/radio/src/eeprom_conversions.cpp b/radio/src/eeprom_conversions.cpp index 00adb9ade..59dd3f776 100644 --- a/radio/src/eeprom_conversions.cpp +++ b/radio/src/eeprom_conversions.cpp @@ -303,7 +303,7 @@ PACK(typedef struct { }) param; uint8_t mode:2; uint8_t active:6; -}) CustomFnData_v215; +}) CustomFunctionData_v215; #else PACK(typedef struct { int8_t swtch; @@ -318,7 +318,7 @@ PACK(typedef struct { }) param; uint8_t mode:2; uint8_t active:6; -}) CustomFnData_v215; +}) CustomFunctionData_v215; #endif PACK(typedef struct { @@ -365,7 +365,7 @@ PACK(typedef struct { int8_t points[NUM_POINTS]; LogicalSwitchData_v215 logicalSw[NUM_LOGICAL_SWITCH]; - CustomFnData_v215 funcSw[32]; + CustomFunctionData_v215 customFn[32]; SwashRingData swashR; FlightModeData_v215 flightModeData[MAX_FLIGHT_MODES]; @@ -407,7 +407,7 @@ PACK(typedef struct { int8_t points[NUM_POINTS]; LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH]; - CustomFnData funcSw[NUM_CFN]; + CustomFunctionData customFn[NUM_CFN]; SwashRingData swashR; FlightModeData flightModeData[MAX_FLIGHT_MODES]; @@ -950,9 +950,9 @@ void ConvertModel_215_to_216(ModelData &model) } } for (uint8_t i=0; i<32; i++) { - CustomFnData & fn = newModel.funcSw[i]; - fn.swtch = ConvertSwitch_215_to_216(oldModel.funcSw[i].swtch); - fn.func = oldModel.funcSw[i].func; + CustomFunctionData & fn = newModel.customFn[i]; + fn.swtch = ConvertSwitch_215_to_216(oldModel.customFn[i].swtch); + fn.func = oldModel.customFn[i].func; if (fn.func <= 15) { fn.all.param = fn.func; fn.func = FUNC_OVERRIDE_CHANNEL; @@ -1001,20 +1001,20 @@ void ConvertModel_215_to_216(ModelData &model) } else { fn.all.param = fn.func - 32 - IS_PCBSKY9X; - fn.all.mode = oldModel.funcSw[i].mode; + fn.all.mode = oldModel.customFn[i].mode; fn.func = FUNC_ADJUST_GVAR; } - fn.active = oldModel.funcSw[i].active; + fn.active = oldModel.customFn[i].active; if (HAS_REPEAT_PARAM(fn.func)) { fn.active *= 5; } if (fn.func == FUNC_PLAY_TRACK || fn.func == FUNC_BACKGND_MUSIC) { - memcpy(fn.play.name, oldModel.funcSw[i].param.name, 8); + memcpy(fn.play.name, oldModel.customFn[i].param.name, 8); } else { - fn.all.val = oldModel.funcSw[i].param.composite.val; + fn.all.val = oldModel.customFn[i].param.composite.val; } if (fn.func == FUNC_PLAY_VALUE || fn.func == FUNC_VOLUME || (IS_ADJUST_GV_FUNC(fn.func) && fn.all.mode == FUNC_ADJUST_GVAR_SOURCE)) { #if defined(PCBTARANIS) @@ -1199,8 +1199,8 @@ void ConvertModel_216_to_217(ModelData &model) } } for (int i=0; i + * - Andreas Weitl + * - Bertrand Songis + * - Bryan J. Rentoul (Gruvin) + * - Cameron Weeks + * - Erez Raviv + * - Gabriel Birkus + * - Jean-Pierre Parisy + * - Karl Szmutny + * - Michael Blandford + * - Michal Hlavinka + * - Pat Mackenzie + * - Philip Moss + * - Rob Thomson + * - Romolo Manfredini + * - Thomas Husterer + * + * opentx is based on code named + * gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/, + * er9x by Erez Raviv: http://code.google.com/p/er9x/, + * and the original (and ongoing) project by + * Thomas Husterer, th9x: http://code.google.com/p/th9x/ + * + * 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" + +CustomFunctionsContext modelFunctionsContext = { 0 }; + +#if defined(CPUARM) +CustomFunctionsContext globalFunctionsContext = { 0 }; +#endif + + +#if defined(DEBUG) +/* + * This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES + */ +void testFunc() +{ +#ifdef SIMU + printf("testFunc\n"); fflush(stdout); +#endif +} +#endif + +#if defined(VOICE) +PLAY_FUNCTION(playValue, uint8_t idx) +{ + if (IS_FAI_FORBIDDEN(idx)) + return; + + getvalue_t val = getValue(idx); + + switch (idx) { +#if defined(CPUARM) + case MIXSRC_FIRST_TELEM+TELEM_TX_TIME-1: + PLAY_DURATION(val*60, PLAY_TIME); + break; +#endif + case MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1: + PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1); + break; + case MIXSRC_FIRST_TELEM+TELEM_TIMER1-1: + case MIXSRC_FIRST_TELEM+TELEM_TIMER2-1: +#if defined(CPUARM) + case MIXSRC_FIRST_TELEM+TELEM_TIMER3-1: +#endif + PLAY_DURATION(val, 0); + break; +#if defined(CPUARM) && defined(FRSKY) + case MIXSRC_FIRST_TELEM+TELEM_SWR-1: + PLAY_NUMBER(val, 0, 0); + break; +#endif +#if defined(FRSKY) + case MIXSRC_FIRST_TELEM+TELEM_RSSI_TX-1: + case MIXSRC_FIRST_TELEM+TELEM_RSSI_RX-1: + PLAY_NUMBER(val, 1+UNIT_DBM, 0); + break; + case MIXSRC_FIRST_TELEM+TELEM_MIN_A1-1: + case MIXSRC_FIRST_TELEM+TELEM_MIN_A2-1: +#if defined(CPUARM) + case MIXSRC_FIRST_TELEM+TELEM_MIN_A3-1: + case MIXSRC_FIRST_TELEM+TELEM_MIN_A4-1: +#endif + idx -= TELEM_MIN_A1-TELEM_A1; + // no break + case MIXSRC_FIRST_TELEM+TELEM_A1-1: + case MIXSRC_FIRST_TELEM+TELEM_A2-1: +#if defined(CPUARM) + case MIXSRC_FIRST_TELEM+TELEM_A3-1: + case MIXSRC_FIRST_TELEM+TELEM_A4-1: +#endif + if (TELEMETRY_STREAMING()) { + idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1); + uint8_t att = 0; + int16_t converted_value = div10_and_round(applyChannelRatio(idx, val));; + if (ANA_CHANNEL_UNIT(idx) < UNIT_RAW) { + att = PREC1; + } + PLAY_NUMBER(converted_value, 1+ANA_CHANNEL_UNIT(idx), att); + } + break; + case MIXSRC_FIRST_TELEM+TELEM_CELL-1: + case MIXSRC_FIRST_TELEM+TELEM_MIN_CELL-1: + PLAY_NUMBER(div10_and_round(val), 1+UNIT_VOLTS, PREC1); + break; + + case MIXSRC_FIRST_TELEM+TELEM_VFAS-1: + case MIXSRC_FIRST_TELEM+TELEM_CELLS_SUM-1: + case MIXSRC_FIRST_TELEM+TELEM_MIN_CELLS_SUM-1: + case MIXSRC_FIRST_TELEM+TELEM_MIN_VFAS-1: + PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1); + break; + + case MIXSRC_FIRST_TELEM+TELEM_CURRENT-1: + case MIXSRC_FIRST_TELEM+TELEM_MAX_CURRENT-1: + PLAY_NUMBER(val, 1+UNIT_AMPS, PREC1); + break; + + case MIXSRC_FIRST_TELEM+TELEM_ACCx-1: + case MIXSRC_FIRST_TELEM+TELEM_ACCy-1: + case MIXSRC_FIRST_TELEM+TELEM_ACCz-1: + PLAY_NUMBER(div10_and_round(val), 1+UNIT_G, PREC1); + break; + + case MIXSRC_FIRST_TELEM+TELEM_VSPEED-1: + PLAY_NUMBER(div10_and_round(val), 1+UNIT_METERS_PER_SECOND, PREC1); + break; + + case MIXSRC_FIRST_TELEM+TELEM_ASPEED-1: + case MIXSRC_FIRST_TELEM+TELEM_MAX_ASPEED-1: + PLAY_NUMBER(val/10, 1+UNIT_KTS, 0); + break; + + case MIXSRC_FIRST_TELEM+TELEM_CONSUMPTION-1: + PLAY_NUMBER(val, 1+UNIT_MAH, 0); + break; + + case MIXSRC_FIRST_TELEM+TELEM_POWER-1: + PLAY_NUMBER(val, 1+UNIT_WATTS, 0); + break; + + case MIXSRC_FIRST_TELEM+TELEM_ALT-1: +#if defined(PCBTARANIS) + PLAY_NUMBER(div10_and_round(val), 1+UNIT_DIST, PREC1); + break; +#endif + case MIXSRC_FIRST_TELEM+TELEM_MIN_ALT-1: + case MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1: +#if defined(WS_HOW_HIGH) + if (IS_IMPERIAL_ENABLE() && IS_USR_PROTO_WS_HOW_HIGH()) + PLAY_NUMBER(val, 1+UNIT_FEET, 0); + else +#endif + PLAY_NUMBER(val, 1+UNIT_DIST, 0); + break; + + case MIXSRC_FIRST_TELEM+TELEM_RPM-1: + case MIXSRC_FIRST_TELEM+TELEM_MAX_RPM-1: + { + getvalue_t rpm = val; + if (rpm > 100) + rpm = 10 * div10_and_round(rpm); + if (rpm > 1000) + rpm = 10 * div10_and_round(rpm); + PLAY_NUMBER(rpm, 1+UNIT_RPMS, 0); + break; + } + + case MIXSRC_FIRST_TELEM+TELEM_HDG-1: + PLAY_NUMBER(val, 1+UNIT_HDG, 0); + break; + + default: + { + uint8_t unit = 1; + if (idx < MIXSRC_GVAR1) + val = calcRESXto100(val); + if (idx >= MIXSRC_FIRST_TELEM+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_GPSALT-1) + unit = idx - (MIXSRC_FIRST_TELEM+TELEM_ALT-1); + else if (idx >= MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_MAX_DIST-1) + unit = 3 + idx - (MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1); + + unit = pgm_read_byte(bchunit_ar+unit); + PLAY_NUMBER(val, unit == UNIT_RAW ? 0 : unit+1, 0); + break; + } +#else + default: + { + PLAY_NUMBER(val, 0, 0); + break; + } +#endif + } +} +#endif + +#if defined(CPUARM) +void playCustomFunctionFile(const CustomFunctionData *sd, uint8_t id) +{ + if (sd->play.name[0] != '\0') { + char filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)+sizeof(SOUNDS_EXT)] = SOUNDS_PATH "/"; + strncpy(filename+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); + strncpy(filename+sizeof(SOUNDS_PATH), sd->play.name, sizeof(sd->play.name)); + filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)] = '\0'; + strcat(filename+sizeof(SOUNDS_PATH), SOUNDS_EXT); + PLAY_FILE(filename, sd->func==FUNC_BACKGND_MUSIC ? PLAY_BACKGROUND : 0, id); + } +} +#endif + +#if defined(CPUARM) +#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting +getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range +#endif + +#if defined(CPUARM) +void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext) +#else +#define functions g_model.customFn +#define functionsContext modelFunctionsContext +void evalFunctions() +#endif +{ + MASK_FUNC_TYPE newActiveFunctions = 0; + MASK_CFN_TYPE newActiveSwitches = 0; + +#if defined(ROTARY_ENCODERS) && defined(GVARS) + static rotenc_t rePreviousValues[ROTARY_ENCODERS]; +#endif + +#if defined(OVERRIDE_CHANNEL_FUNCTION) + for (uint8_t i=0; i 0) { + mask = (1<<(CFN_CH_INDEX(cfn)-1)); + } + newActiveFunctions |= mask; + break; + } + + case FUNC_INSTANT_TRIM: + newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM); + if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) { + if (g_menuStack[0] == menuMainView +#if defined(FRSKY) + || g_menuStack[0] == menuTelemetryFrsky +#endif +#if defined(PCBTARANIS) + || g_menuStack[0] == menuMainViewChannelsMonitor + || g_menuStack[0] == menuChannelsView +#endif + ) { + instantTrim(); + } + } + break; + + case FUNC_RESET: + switch (CFN_PARAM(cfn)) { + case FUNC_RESET_TIMER1: + case FUNC_RESET_TIMER2: +#if defined(CPUARM) + case FUNC_RESET_TIMER3: +#endif + timerReset(CFN_PARAM(cfn)); + break; + case FUNC_RESET_FLIGHT: + flightReset(); + break; +#if defined(FRSKY) + case FUNC_RESET_TELEMETRY: + telemetryReset(); + break; +#endif +#if ROTARY_ENCODERS > 0 + case FUNC_RESET_ROTENC1: +#if ROTARY_ENCODERS > 1 + case FUNC_RESET_ROTENC2: +#endif + g_rotenc[CFN_PARAM(cfn)-FUNC_RESET_ROTENC1] = 0; + break; +#endif + } + break; + +#if defined(CPUARM) + case FUNC_SET_TIMER: + { + TimerState & timerState = timersStates[CFN_TIMER_INDEX(cfn)]; + timerState.state = TMR_OFF; // is changed to RUNNING dep from mode + timerState.val = CFN_PARAM(cfn); + timerState.val_10ms = 0 ; + break; + } +#endif + +#if defined(GVARS) + case FUNC_ADJUST_GVAR: + if (CFN_GVAR_MODE(cfn) == 0) { + SET_GVAR(CFN_GVAR_INDEX(cfn), CFN_PARAM(cfn), mixerCurrentFlightMode); + } + else if (CFN_GVAR_MODE(cfn) == 2) { + SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_PARAM(cfn), mixerCurrentFlightMode), mixerCurrentFlightMode); + } + else if (CFN_GVAR_MODE(cfn) == 3) { + if (!(functionsContext.activeSwitches & switch_mask)) { + SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + (CFN_PARAM(cfn) ? +1 : -1), mixerCurrentFlightMode); + } + } + else if (CFN_PARAM(cfn) >= MIXSRC_TrimRud && CFN_PARAM(cfn) <= MIXSRC_TrimAil) { + trimGvar[CFN_PARAM(cfn)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(cfn); + } +#if defined(ROTARY_ENCODERS) + else if (CFN_PARAM(cfn) >= MIXSRC_REa && CFN_PARAM(cfn) < MIXSRC_TrimRud) { + int8_t scroll = rePreviousValues[CFN_PARAM(cfn)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(cfn)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY); + if (scroll) { + SET_GVAR(CFN_GVAR_INDEX(cfn), GVAR_VALUE(CFN_GVAR_INDEX(cfn), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(cfn))) + scroll, mixerCurrentFlightMode); + } + } +#endif + else { + SET_GVAR(CFN_GVAR_INDEX(cfn), calcRESXto100(getValue(CFN_PARAM(cfn))), mixerCurrentFlightMode); + } + break; +#endif + +#if defined(CPUARM) && defined(SDCARD) + case FUNC_VOLUME: + { + getvalue_t raw = getValue(CFN_PARAM(cfn)); + //only set volume if input changed more than hysteresis + if (abs(requiredSpeakerVolumeRawLast - raw) > VOLUME_HYSTERESIS) { + requiredSpeakerVolumeRawLast = raw; + } + requiredSpeakerVolume = ((1024 + requiredSpeakerVolumeRawLast) * VOLUME_LEVEL_MAX) / 2048; + break; + } +#endif + +#if defined(CPUARM) && defined(SDCARD) + case FUNC_PLAY_SOUND: + case FUNC_PLAY_TRACK: + case FUNC_PLAY_VALUE: +#if defined(HAPTIC) + case FUNC_HAPTIC: +#endif + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(cfn); + if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART) { + functionsContext.lastFunctionTime[i] = tmr10ms; + } + if (!functionsContext.lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=100*repeatParam)) { + if (!IS_PLAYING(i+1)) { + functionsContext.lastFunctionTime[i] = tmr10ms; + if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) { + AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn)); + } + else if (CFN_FUNC(cfn) == FUNC_PLAY_VALUE) { + PLAY_VALUE(CFN_PARAM(cfn), i+1); + } +#if defined(HAPTIC) + else if (CFN_FUNC(cfn) == FUNC_HAPTIC) { + haptic.event(AU_FRSKY_LAST+CFN_PARAM(cfn)); + } +#endif + else { + playCustomFunctionFile(cfn, i+1); + } + } + } + break; + } + + case FUNC_BACKGND_MUSIC: + newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC); + if (!IS_PLAYING(i+1)) { + playCustomFunctionFile(cfn, i+1); + } + break; + + case FUNC_BACKGND_MUSIC_PAUSE: + newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC_PAUSE); + break; + +#elif defined(VOICE) + case FUNC_PLAY_SOUND: + case FUNC_PLAY_TRACK: + case FUNC_PLAY_BOTH: + case FUNC_PLAY_VALUE: + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(cfn); + if (!functionsContext.lastFunctionTime[i] || (CFN_FUNC(cfn)==FUNC_PLAY_BOTH && active!=(bool)(functionsContext.activeSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) { + functionsContext.lastFunctionTime[i] = tmr10ms; + uint8_t param = CFN_PARAM(cfn); + if (CFN_FUNC(cfn) == FUNC_PLAY_SOUND) { + AUDIO_PLAY(AU_FRSKY_FIRST+param); + } + else if (CFN_FUNC(cfn) == FUNC_PLAY_VALUE) { + PLAY_VALUE(param, i+1); + } + else { +#if defined(GVARS) + if (CFN_FUNC(cfn) == FUNC_PLAY_TRACK && param > 250) + param = GVAR_VALUE(param-251, getGVarFlightPhase(mixerCurrentFlightMode, param-251)); +#endif + PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1); + } + } + if (!active) { + // PLAY_BOTH would change activeFnSwitches otherwise + switch_mask = 0; + } + break; + } +#else + case FUNC_PLAY_SOUND: + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(cfn); + if (!functionsContext.lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) { + functionsContext.lastFunctionTime[i] = tmr10ms; + AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(cfn)); + } + break; + } +#endif + +#if defined(FRSKY) && defined(VARIO) + case FUNC_VARIO: + newActiveFunctions |= (1 << FUNCTION_VARIO); + break; +#endif + +#if defined(HAPTIC) && !defined(CPUARM) + case FUNC_HAPTIC: + { + tmr10ms_t tmr10ms = get_tmr10ms(); + uint8_t repeatParam = CFN_PLAY_REPEAT(cfn); + if (!functionsContext.lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-functionsContext.lastFunctionTime[i])>=1000*repeatParam)) { + functionsContext.lastFunctionTime[i] = tmr10ms; + haptic.event(AU_FRSKY_LAST+CFN_PARAM(cfn)); + } + break; + } +#endif + +#if defined(SDCARD) + case FUNC_LOGS: + if (CFN_PARAM(cfn)) { + newActiveFunctions |= (1 << FUNCTION_LOGS); + logDelay = CFN_PARAM(cfn); + } + break; +#endif + + case FUNC_BACKLIGHT: + newActiveFunctions |= (1 << FUNCTION_BACKLIGHT); + break; + +#if defined(DEBUG) + case FUNC_TEST: + testFunc(); + break; +#endif + } + + newActiveSwitches |= switch_mask; + } + else { + functionsContext.lastFunctionTime[i] = 0; + } + } + } + + functionsContext.activeSwitches = newActiveSwitches; + functionsContext.activeFunctions = newActiveFunctions; + +#if defined(ROTARY_ENCODERS) && defined(GVARS) + for (uint8_t i=0; i 0) s_editMode = 0; @@ -1128,6 +1131,14 @@ void menuGeneralSdManager(uint8_t _event) } #endif +#if defined(CPUARM) +void menuGeneralCustomFunctions(uint8_t event) +{ + MENU(STR_MENUGLOBALFUNCS, menuTabGeneral, e_GeneralCustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); + return menuCustomFunctions(event, g_eeGeneral.customFn, globalFunctionsContext); +} +#endif + #if LCD_W >= 212 #define TRAINER_CALIB_POS 12 #else @@ -1139,7 +1150,7 @@ void menuGeneralTrainer(uint8_t event) uint8_t y; bool slave = SLAVE_MODE(); - MENU(STR_MENUTRAINER, menuTabDiag, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/}); + MENU(STR_MENUTRAINER, menuTabGeneral, e_Trainer, (slave ? 1 : 7), {0, 2, 2, 2, 2, 0/*, 0*/}); if (slave) { lcd_puts(7*FW, 4*FH, STR_SLAVE); @@ -1211,7 +1222,7 @@ void menuGeneralTrainer(uint8_t event) void menuGeneralVersion(uint8_t event) { - SIMPLE_MENU(STR_MENUVERSION, menuTabDiag, e_Vers, 1); + SIMPLE_MENU(STR_MENUVERSION, menuTabGeneral, e_Vers, 1); lcd_putsLeft(MENU_TITLE_HEIGHT+FH, vers_stamp); @@ -1241,7 +1252,7 @@ void displayKeyState(uint8_t x, uint8_t y, EnumKeys key) void menuGeneralDiagKeys(uint8_t event) { - SIMPLE_MENU(STR_MENUDIAG, menuTabDiag, e_Keys, 1); + SIMPLE_MENU(STR_MENUDIAG, menuTabGeneral, e_Keys, 1); lcd_puts(14*FW, MENU_TITLE_HEIGHT+2*FH, STR_VTRIM); @@ -1289,7 +1300,7 @@ void menuGeneralDiagAna(uint8_t event) #define ANAS_ITEMS_COUNT 2 #endif - SIMPLE_MENU(STR_MENUANA, menuTabDiag, e_Ana, ANAS_ITEMS_COUNT); + SIMPLE_MENU(STR_MENUANA, menuTabGeneral, e_Ana, ANAS_ITEMS_COUNT); STICK_SCROLL_DISABLE(); @@ -1362,7 +1373,7 @@ enum menuGeneralHwItems { void menuGeneralHardware(uint8_t event) { - MENU(STR_HARDWARE, menuTabDiag, e_Hardware, ITEM_SETUP_HW_MAX+1, {0}); + MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0}); uint8_t sub = m_posVert - 1; @@ -1417,7 +1428,7 @@ enum menuGeneralHwItems { #define GENERAL_HW_PARAM_OFS (2+(15*FW)) void menuGeneralHardware(uint8_t event) { - MENU(STR_HARDWARE, menuTabDiag, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)}); + MENU(STR_HARDWARE, menuTabGeneral, e_Hardware, ITEM_SETUP_HW_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, IF_ROTARY_ENCODERS(0) CASE_BLUETOOTH(0)}); uint8_t sub = m_posVert - 1; @@ -1636,7 +1647,7 @@ void menuCommonCalib(uint8_t event) void menuGeneralCalib(uint8_t event) { - check_simple(event, e_Calib, menuTabDiag, DIM(menuTabDiag), 0); + check_simple(event, e_Calib, menuTabGeneral, DIM(menuTabGeneral), 0); if (menuEvent) { calibrationState = 0; diff --git a/radio/src/gui/menu_model.cpp b/radio/src/gui/menu_model.cpp index e48254c8b..da5edc468 100644 --- a/radio/src/gui/menu_model.cpp +++ b/radio/src/gui/menu_model.cpp @@ -4410,18 +4410,18 @@ enum LogicalSwitchFields { #endif #if defined(CPUARM) - #define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL; IsValueAvailable isValueAvailable = NULL - #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f)) + #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL + #define INCDEC_SET_FLAG(f) incdecFlag = (f) #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable) #elif defined(CPUM64) - #define INCDEC_DECLARE_VARS() + #define INCDEC_DECLARE_VARS(f) #define INCDEC_SET_FLAG(f) #define INCDEC_ENABLE_CHECK(fn) #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL) #else - #define INCDEC_DECLARE_VARS() uint8_t incdecFlag = EE_MODEL - #define INCDEC_SET_FLAG(f) incdecFlag = (EE_MODEL|(f)) + #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f) + #define INCDEC_SET_FLAG(f) incdecFlag = (f) #define INCDEC_ENABLE_CHECK(fn) #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag) #endif @@ -4458,7 +4458,7 @@ void menuModelLogicalSwitchOne(uint8_t event) int8_t sub = m_posVert; - INCDEC_DECLARE_VARS(); + INCDEC_DECLARE_VARS(EE_MODEL); int v1_val = cs->v1; @@ -4502,7 +4502,7 @@ void menuModelLogicalSwitchOne(uint8_t event) else { v1_val = (uint8_t)cs->v1; putsMixerSource(CSWONE_2ND_COLUMN, y, v1_val, attr); - INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } if (attr) { @@ -4533,7 +4533,7 @@ void menuModelLogicalSwitchOne(uint8_t event) } else if (cstate == LS_FAMILY_COMP) { putsMixerSource(CSWONE_2ND_COLUMN, y, cs->v2, attr); - INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } else { @@ -4547,7 +4547,7 @@ void menuModelLogicalSwitchOne(uint8_t event) v2_min = 0; else v2_min = minTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1); - INCDEC_SET_FLAG(INCDEC_REP10 | NO_INCDEC_MARKS); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS); if (cs->v2 < v2_min || cs->v2 > v2_max) { cs->v2 = 0; eeDirty(EE_MODEL); @@ -4675,7 +4675,7 @@ struct Clipboard { ClipboardType type; union { LogicalSwitchData csw; - CustomFnData cfn; + CustomFunctionData cfn; } data; }; @@ -4703,7 +4703,7 @@ void onLogicalSwitchesMenu(const char *result) void menuModelLogicalSwitches(uint8_t event) { - INCDEC_DECLARE_VARS(); + INCDEC_DECLARE_VARS(EE_MODEL); MENU(STR_MENULOGICALSWITCHES, menuTabModel, e_LogicalSwitches, NUM_LOGICAL_SWITCH+1, {0, NAVIGATION_LINE_BY_LINE|LS_FIELD_LAST/*repeated...*/}); @@ -4761,7 +4761,7 @@ void menuModelLogicalSwitches(uint8_t event) putsSwitches(CSW_3RD_COLUMN, y, cs->v2, attr2); v1_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v1_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; v2_min = SWSRC_FIRST_IN_LOGICAL_SWITCHES; v2_max = SWSRC_LAST_IN_LOGICAL_SWITCHES; - INCDEC_SET_FLAG(INCDEC_SWITCH); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH); INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches); } #if defined(CPUARM) @@ -4772,11 +4772,11 @@ void menuModelLogicalSwitches(uint8_t event) v2_min=-129; v2_max = 122; v3_max = 222 - cs->v2; if (horz == 1) { - INCDEC_SET_FLAG(INCDEC_SWITCH); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH); INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches); } else { - INCDEC_SET_FLAG(0); + INCDEC_SET_FLAG(EE_MODEL); INCDEC_ENABLE_CHECK(NULL); } } @@ -4787,7 +4787,7 @@ void menuModelLogicalSwitches(uint8_t event) #endif putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); putsMixerSource(CSW_3RD_COLUMN, y, cs->v2, attr2); - INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } else if (cstate == LS_FAMILY_TIMER) { @@ -4795,7 +4795,7 @@ void menuModelLogicalSwitches(uint8_t event) lcd_outdezAtt(CSW_3RD_COLUMN, y, lswTimerValue(cs->v2), LEFT|PREC1|attr2); v1_min = v2_min = -128; v1_max = v2_max = 122; - INCDEC_SET_FLAG(0); + INCDEC_SET_FLAG(EE_MODEL); INCDEC_ENABLE_CHECK(NULL); } else { @@ -4804,11 +4804,11 @@ void menuModelLogicalSwitches(uint8_t event) #endif putsMixerSource(CSW_2ND_COLUMN, y, v1_val, attr1); if (horz == 1) { - INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } else { - INCDEC_SET_FLAG(0); + INCDEC_SET_FLAG(EE_MODEL); INCDEC_ENABLE_CHECK(NULL); } #if defined(FRSKY) @@ -4823,7 +4823,7 @@ void menuModelLogicalSwitches(uint8_t event) else v2_min = minTelemValue(v1_val - MIXSRC_FIRST_TELEM + 1); if (horz == 2 && v2_max-v2_min > 1000) - INCDEC_SET_FLAG(INCDEC_REP10 | NO_INCDEC_MARKS); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_REP10 | NO_INCDEC_MARKS); if (cs->v2 < v2_min || cs->v2 > v2_max) { cs->v2 = 0; eeDirty(EE_MODEL); @@ -4955,7 +4955,7 @@ void menuModelLogicalSwitches(uint8_t event) #endif case LS_FIELD_ANDSW: #if defined(CPUARM) - INCDEC_SET_FLAG(INCDEC_SWITCH); + INCDEC_SET_FLAG(EE_MODEL | INCDEC_SWITCH); INCDEC_ENABLE_CHECK(isSwitchAvailableInLogicalSwitches); cs->andsw = CHECK_INCDEC_PARAM(event, cs->andsw, -MAX_LS_ANDSW, MAX_LS_ANDSW); #else @@ -4998,7 +4998,7 @@ void menuModelLogicalSwitches(uint8_t event) void onCustomFunctionsFileSelectionMenu(const char *result) { int8_t sub = m_posVert - 1; - CustomFnData * cf = &g_model.funcSw[sub]; + CustomFunctionData * cf = &g_model.customFn[sub]; uint8_t func = CFN_FUNC(cf); if (result == STR_UPDATE_LIST) { @@ -5030,7 +5030,17 @@ void onCustomFunctionsFileSelectionMenu(const char *result) void onCustomFunctionsMenu(const char *result) { int8_t sub = m_posVert-1; - CustomFnData * cfn = &g_model.funcSw[sub]; + CustomFunctionData * cfn; + uint8_t eeFlags; + + if (g_menuStack[0] == menuModelCustomFunctions) { + cfn = &g_model.customFn[sub]; + eeFlags = EE_MODEL; + } + else { + cfn = &g_eeGeneral.customFn[sub]; + eeFlags = EE_GENERAL; + } if (result == STR_COPY) { clipboard.type = CLIPBOARD_TYPE_CUSTOM_FUNCTION; @@ -5038,45 +5048,47 @@ void onCustomFunctionsMenu(const char *result) } else if (result == STR_PASTE) { *cfn = clipboard.data.cfn; - eeDirty(EE_MODEL); + eeDirty(eeFlags); } else if (result == STR_CLEAR) { - memset(cfn, 0, sizeof(CustomFnData)); - eeDirty(EE_MODEL); + memset(cfn, 0, sizeof(CustomFunctionData)); + eeDirty(eeFlags); } else if (result == STR_INSERT) { - memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFnData)); - memset(cfn, 0, sizeof(CustomFnData)); - eeDirty(EE_MODEL); + memmove(cfn+1, cfn, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); + memset(cfn, 0, sizeof(CustomFunctionData)); + eeDirty(eeFlags); } else if (result == STR_DELETE) { - memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFnData)); - memset(&g_model.funcSw[NUM_CFN-1], 0, sizeof(CustomFnData)); - eeDirty(EE_MODEL); + memmove(cfn, cfn+1, (NUM_CFN-sub-1)*sizeof(CustomFunctionData)); + memset(&g_model.customFn[NUM_CFN-1], 0, sizeof(CustomFunctionData)); + eeDirty(eeFlags); } } #endif -void menuModelCustomFunctions(uint8_t event) +void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext) { - MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); - int8_t sub = m_posVert - 1; +#if defined(CPUARM) || defined(AUTOSWITCH) + uint8_t eeFlags = (functions == g_model.customFn) ? EE_MODEL : EE_GENERAL; +#endif + #if defined(PCBTARANIS) if (sub>=0 && m_posHorz<0 && event==EVT_KEY_LONG(KEY_ENTER) && !READ_ONLY()) { killEvents(event); - CustomFnData *sd = &g_model.funcSw[sub]; - if (!CFN_EMPTY(sd)) + CustomFunctionData *cfn = &functions[sub]; + if (!CFN_EMPTY(cfn)) MENU_ADD_ITEM(STR_COPY); if (clipboard.type == CLIPBOARD_TYPE_CUSTOM_FUNCTION) MENU_ADD_ITEM(STR_PASTE); - if (!CFN_EMPTY(sd) && CFN_EMPTY(&g_model.funcSw[NUM_CFN-1])) + if (!CFN_EMPTY(cfn) && CFN_EMPTY(&functions[NUM_CFN-1])) MENU_ADD_ITEM(STR_INSERT); - if (!CFN_EMPTY(sd)) + if (!CFN_EMPTY(cfn)) MENU_ADD_ITEM(STR_CLEAR); for (int i=sub+1; i0) ? BLINK|INVERS : INVERS) : 0); uint8_t active = (attr && (s_editMode>0 || p1valdiff)); switch (j) { case 0: - putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(sd), attr | ((activeFnSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); - if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_MODELSWITCH(event, CFN_SWITCH(sd), SWSRC_FIRST, SWSRC_LAST, isSwitchAvailableInCustomFunctions); + putsSwitches(MODEL_CUSTOM_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext.activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); + if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); break; case 1: - if (CFN_SWITCH(sd)) { + if (CFN_SWITCH(cfn)) { +#if defined(CPUARM) + if (func == FUNC_OVERRIDE_CHANNEL) { + func = CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable); + } +#endif lcd_putsiAtt(MODEL_CUSTOM_FUNC_2ND_COLUMN, y, STR_VFSWFUNC, func, attr); if (active) { #if defined(CPUARM) - CFN_FUNC(sd) = checkIncDec(event, CFN_FUNC(sd), 0, FUNC_MAX-1, EE_MODEL, isAssignableFunctionAvailable); + CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable); #else - CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(sd), FUNC_MAX-1); + CHECK_INCDEC_MODELVAR_ZERO(event, CFN_FUNC(cfn), FUNC_MAX-1); #endif - if (checkIncDec_Ret) CFN_RESET(sd); + if (checkIncDec_Ret) CFN_RESET(cfn); } } else { @@ -5129,45 +5146,49 @@ void menuModelCustomFunctions(uint8_t event) int8_t maxParam = NUM_CHNOUT-1; #if defined(OVERRIDE_CHANNEL_FUNCTION) if (func == FUNC_OVERRIDE_CHANNEL) { - putsChn(lcdNextPos, y, CFN_CH_INDEX(sd)+1, attr); + putsChn(lcdNextPos, y, CFN_CH_INDEX(cfn)+1, attr); } else #endif if (func == FUNC_TRAINER) { maxParam = 4; #if defined(CPUARM) - putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(sd)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(sd)-1, attr); + putsMixerSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); #else - putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(sd)-1, attr); + putsMixerSource(lcdNextPos, y, MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); #endif } #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { maxParam = MAX_GVARS-1; - putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(sd)+1, attr); - if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_INDEX(sd), maxParam); + putsStrIdx(lcdNextPos, y, STR_GV, CFN_GVAR_INDEX(cfn)+1, attr); +#if defined(CPUARM) + if (active) CFN_GVAR_INDEX(cfn) = checkIncDec(event, CFN_GVAR_INDEX(cfn), 0, maxParam, eeFlags); +#else + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_GVAR_INDEX(cfn), maxParam); +#endif break; } #endif #if defined(CPUARM) else if (func == FUNC_SET_TIMER) { maxParam = MAX_TIMERS-1; - putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(sd)+1, attr); - if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_TIMER_INDEX(sd), maxParam); + putsStrIdx(lcdNextPos, y, STR_TIMER, CFN_TIMER_INDEX(cfn)+1, attr); + if (active) CFN_TIMER_INDEX(cfn) = checkIncDec(event, CFN_TIMER_INDEX(cfn), 0, maxParam, eeFlags); break; } #endif else if (attr) { REPEAT_LAST_CURSOR_MOVE(); } - if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(sd), maxParam); + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_CH_INDEX(cfn), maxParam); break; } case 3: { - INCDEC_DECLARE_VARS(); - int16_t val_displayed = CFN_PARAM(sd); + INCDEC_DECLARE_VARS(eeFlags); + int16_t val_displayed = CFN_PARAM(cfn); #if defined(CPUARM) int16_t val_min = 0; int16_t val_max = 255; @@ -5177,12 +5198,12 @@ void menuModelCustomFunctions(uint8_t event) #endif if (func == FUNC_RESET) { val_max = FUNC_RESET_PARAM_LAST; - lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(sd), attr); + lcd_putsiAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, STR_VFSWRESET, CFN_PARAM(cfn), attr); } #if defined(OVERRIDE_CHANNEL_FUNCTION) else if (func == FUNC_OVERRIDE_CHANNEL) { #if !defined(CPUARM) - val_displayed = (int8_t)CFN_PARAM(sd); + val_displayed = (int8_t)CFN_PARAM(cfn); #endif val_min = -LIMIT_EXT_PERCENT; val_max = +LIMIT_EXT_PERCENT; lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); @@ -5213,8 +5234,8 @@ void menuModelCustomFunctions(uint8_t event) #else coord_t x = (func == FUNC_PLAY_TRACK ? MODEL_CUSTOM_FUNC_2ND_COLUMN + FW + FW*strlen(TR_PLAY_TRACK) : MODEL_CUSTOM_FUNC_3RD_COLUMN); #endif - if (ZEXIST(sd->play.name)) - lcd_putsnAtt(x, y, sd->play.name, sizeof(sd->play.name), attr); + if (ZEXIST(cfn->play.name)) + lcd_putsnAtt(x, y, cfn->play.name, sizeof(cfn->play.name), attr); else lcd_putsiAtt(x, y, STR_VCSWFUNC, 0, attr); if (active && event==EVT_KEY_BREAK(KEY_ENTER)) { @@ -5227,7 +5248,7 @@ void menuModelCustomFunctions(uint8_t event) strcpy(directory, SOUNDS_PATH); strncpy(directory+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); } - if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(sd->play.name), sd->play.name)) { + if (listSdFiles(directory, func==FUNC_PLAY_SCRIPT ? SCRIPTS_EXT : SOUNDS_EXT, sizeof(cfn->play.name), cfn->play.name)) { menuHandler = onCustomFunctionsFileSelectionMenu; } else { @@ -5247,7 +5268,7 @@ void menuModelCustomFunctions(uint8_t event) else if (func == FUNC_VOLUME) { val_max = MIXSRC_LAST_CH; putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); - INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); } #elif defined(VOICE) @@ -5293,24 +5314,24 @@ void menuModelCustomFunctions(uint8_t event) #endif #if defined(PCBTARANIS) && defined(REVPLUS) else if (func == FUNC_BACKLIGHT) { - displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(sd), 100, attr); - INCDEC_SET_FLAG(NO_INCDEC_MARKS); + displaySlider(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, CFN_PARAM(cfn), 100, attr); + INCDEC_SET_FLAG(eeFlags | NO_INCDEC_MARKS); val_min = 0; val_max = 100; } #endif #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { - switch (CFN_GVAR_MODE(sd)) { + switch (CFN_GVAR_MODE(cfn)) { case FUNC_ADJUST_GVAR_CONSTANT: - val_displayed = (int16_t)CFN_PARAM(sd); + val_displayed = (int16_t)CFN_PARAM(cfn); val_min = -CFN_GVAR_CST_MAX; val_max = +CFN_GVAR_CST_MAX; lcd_outdezAtt(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr|LEFT); break; case FUNC_ADJUST_GVAR_SOURCE: val_max = MIXSRC_LAST_CH; putsMixerSource(MODEL_CUSTOM_FUNC_3RD_COLUMN, y, val_displayed, attr); - INCDEC_SET_FLAG(INCDEC_SOURCE); + INCDEC_SET_FLAG(eeFlags | INCDEC_SOURCE); INCDEC_ENABLE_CHECK(isSourceAvailable); break; case FUNC_ADJUST_GVAR_GVAR: @@ -5327,9 +5348,9 @@ void menuModelCustomFunctions(uint8_t event) killEvents(event); s_editMode = !s_editMode; active = true; - CFN_GVAR_MODE(sd) += 1; + CFN_GVAR_MODE(cfn) += 1; #if defined(CPUARM) - CFN_GVAR_MODE(sd) &= 0x03; + CFN_GVAR_MODE(cfn) &= 0x03; #endif val_displayed = 0; } @@ -5340,18 +5361,22 @@ void menuModelCustomFunctions(uint8_t event) } if (active) { - CFN_PARAM(sd) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); + CFN_PARAM(cfn) = CHECK_INCDEC_PARAM(event, val_displayed, val_min, val_max); } break; } case 4: if (HAS_ENABLE_PARAM(func)) { - menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(sd), attr); - if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_ACTIVE(sd), 1); + menu_lcd_onoff(MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); +#if defined(CPUARM) + if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); +#else + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_ACTIVE(cfn), 1); +#endif } else if (HAS_REPEAT_PARAM(func)) { - if (CFN_PLAY_REPEAT(sd) == 0) { + if (CFN_PLAY_REPEAT(cfn) == 0) { #if LCD_W >= 212 lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); #else @@ -5359,7 +5384,7 @@ void menuModelCustomFunctions(uint8_t event) #endif } #if defined(CPUARM) - else if (CFN_PLAY_REPEAT(sd) == CFN_PLAY_REPEAT_NOSTART) { + else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) { #if LCD_W >= 212 lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN-1, y, '!', attr); lcd_putsAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2, y, "1x", attr); @@ -5369,15 +5394,15 @@ void menuModelCustomFunctions(uint8_t event) } #endif else { - lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(sd)*CFN_PLAY_REPEAT_MUL, attr); + lcd_outdezAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr); #if LCD_W >= 212 lcd_putcAtt(MODEL_CUSTOM_FUNC_4TH_COLUMN+2+FW, y, 's', attr); #endif } #if defined(CPUARM) - if (active) CFN_PLAY_REPEAT(sd) = checkIncDecModel(event, CFN_PLAY_REPEAT(sd)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(sd), -1, 60/CFN_PLAY_REPEAT_MUL); + if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags); #else - if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_PLAY_REPEAT(sd), 60/CFN_PLAY_REPEAT_MUL); + if (active) CHECK_INCDEC_MODELVAR_ZERO(event, CFN_PLAY_REPEAT(cfn), 60/CFN_PLAY_REPEAT_MUL); #endif } else if (attr) { @@ -5389,6 +5414,12 @@ void menuModelCustomFunctions(uint8_t event) } } +void menuModelCustomFunctions(uint8_t event) +{ + MENU(STR_MENUCUSTOMFUNC, menuTabModel, e_CustomFunctions, NUM_CFN+1, {0, NAVIGATION_LINE_BY_LINE|4/*repeated*/}); + return menuCustomFunctions(event, g_model.customFn, modelFunctionsContext); +} + #if defined(LUA_MODEL_SCRIPTS) void onModelCustomScriptMenu(const char *result) { diff --git a/radio/src/gui/menus.cpp b/radio/src/gui/menus.cpp index d8fc15a49..95fbbb281 100644 --- a/radio/src/gui/menus.cpp +++ b/radio/src/gui/menus.cpp @@ -1487,7 +1487,8 @@ bool isInputSourceAvailable(int source) enum SwitchContext { LogicalSwitchesContext, - CustomFunctionsContext, + ModelCustomFunctionsContext, + GeneralCustomFunctionsContext, TimersContext, MixesContext }; @@ -1518,17 +1519,22 @@ bool isSwitchAvailable(int swtch, SwitchContext context) } #endif - if (context != LogicalSwitchesContext && swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) { - LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH); - return (cs->func != LS_FUNC_NONE); + if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) { + if (context == GeneralCustomFunctionsContext) { + return false; + } + else if (context != LogicalSwitchesContext) { + LogicalSwitchData * cs = lswAddress(swtch-SWSRC_FIRST_LOGICAL_SWITCH); + return (cs->func != LS_FUNC_NONE); + } } - if (context != CustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) { + if (context != ModelCustomFunctionsContext && context != GeneralCustomFunctionsContext && (swtch == SWSRC_ON || swtch == SWSRC_One)) { return false; } if (swtch >= SWSRC_FIRST_FLIGHT_MODE && swtch <= SWSRC_LAST_FLIGHT_MODE) { - if (context == MixesContext) { + if (context == MixesContext || context == GeneralCustomFunctionsContext) { return false; } else { @@ -1551,7 +1557,10 @@ bool isSwitchAvailableInLogicalSwitches(int swtch) bool isSwitchAvailableInCustomFunctions(int swtch) { - return isSwitchAvailable(swtch, CustomFunctionsContext); + if (g_menuStack[0] == menuModelCustomFunctions) + return isSwitchAvailable(swtch, ModelCustomFunctionsContext); + else + return isSwitchAvailable(swtch, GeneralCustomFunctionsContext); } bool isSwitchAvailableInMixes(int swtch) @@ -1587,15 +1596,23 @@ bool isLogicalSwitchFunctionAvailable(int function) bool isAssignableFunctionAvailable(int function) { + bool modelFunctions = (g_menuStack[0] == menuModelCustomFunctions); + switch (function) { -#if !defined(OVERRIDE_CHANNEL_FUNCTION) case FUNC_OVERRIDE_CHANNEL: +#if defined(OVERRIDE_CHANNEL_FUNCTION) + return modelFunctions; +#else + return false; +#endif + case FUNC_ADJUST_GVAR: +#if defined(GVARS) + return modelFunctions; +#else + return false; #endif #if !defined(HAPTIC) case FUNC_HAPTIC: -#endif -#if !defined(GVARS) - case FUNC_ADJUST_GVAR: #endif case FUNC_PLAY_DIFF: case FUNC_RESERVE1: diff --git a/radio/src/gui/menus.h b/radio/src/gui/menus.h index 0cc6854db..48056863c 100644 --- a/radio/src/gui/menus.h +++ b/radio/src/gui/menus.h @@ -103,6 +103,7 @@ void menu_lcd_onoff(coord_t x, coord_t y, uint8_t value, LcdFlags attr); typedef void (*MenuFuncP)(uint8_t event); typedef void (*MenuFuncP_PROGMEM)(uint8_t event); extern const MenuFuncP_PROGMEM menuTabModel[]; +extern const MenuFuncP_PROGMEM menuTabGeneral[]; extern MenuFuncP g_menuStack[5]; extern uint8_t g_menuPos[4]; @@ -133,6 +134,7 @@ void menuTelemetryFrsky(uint8_t event); #endif void menuGeneralSetup(uint8_t event); void menuGeneralCalib(uint8_t event); +void menuCustomFunctions(uint8_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext); void menuModelSelect(uint8_t event); void menuModelCustomFunctions(uint8_t event); @@ -232,14 +234,20 @@ int8_t checkIncDecGen(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max); bool isSwitchAvailableInTimers(int swtch); bool isModuleAvailable(int module); #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER)) + #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \ + var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH|NO_INCDEC_MARKS, available) #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \ - var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH|NO_INCDEC_MARKS, available) + CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available) #elif defined(AUTOSWITCH) #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER)) + #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \ + var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH) #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \ - var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SWITCH) + CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available) #else #define AUTOSWITCH_ENTER_LONG() (0) + #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \ + CHECK_INCDEC_MODELVAR(event, var, min, max) #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \ CHECK_INCDEC_MODELVAR(event, var, min, max) #endif diff --git a/radio/src/lua.cpp b/radio/src/lua.cpp index d01f68fad..a4fdcfc80 100644 --- a/radio/src/lua.cpp +++ b/radio/src/lua.cpp @@ -998,7 +998,7 @@ static int luaModelGetCustomFunction(lua_State *L) { int idx = luaL_checkunsigned(L, 1); if (idx < NUM_CFN) { - CustomFnData * cfn = &g_model.funcSw[idx]; + CustomFunctionData * cfn = &g_model.customFn[idx]; lua_newtable(L); lua_pushtableinteger(L, "switch", CFN_SWITCH(cfn)); lua_pushtableinteger(L, "func", CFN_FUNC(cfn)); @@ -1022,8 +1022,8 @@ static int luaModelSetCustomFunction(lua_State *L) { int idx = luaL_checkunsigned(L, 1); if (idx < NUM_CFN) { - CustomFnData * cfn = &g_model.funcSw[idx]; - memclear(cfn, sizeof(CustomFnData)); + CustomFunctionData * cfn = &g_model.customFn[idx]; + memclear(cfn, sizeof(CustomFunctionData)); luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string @@ -1668,7 +1668,7 @@ bool luaLoadMixScript(uint8_t index) bool luaLoadFunctionScript(uint8_t index) { - CustomFnData & fn = g_model.funcSw[index]; + CustomFunctionData & fn = g_model.customFn[index]; if (fn.func == FUNC_PLAY_SCRIPT && ZEXIST(fn.play.name)) { if (luaScriptsCount < MAX_SCRIPTS) { @@ -1900,7 +1900,7 @@ void luaDoOneRunPermanentScript(uint8_t evt, int i) } } else if (sid.reference >= SCRIPT_FUNC_FIRST && sid.reference <= SCRIPT_FUNC_LAST) { - CustomFnData & fn = g_model.funcSw[sid.reference-SCRIPT_FUNC_FIRST]; + CustomFunctionData & fn = g_model.customFn[sid.reference-SCRIPT_FUNC_FIRST]; if (!getSwitch(fn.swtch)) { return; } diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index be37379d8..f336703cb 100755 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -1027,7 +1027,13 @@ void evalMixes(uint8_t tick10ms) #if defined(CPUARM) requiredSpeakerVolume = g_eeGeneral.speakerVolume + VOLUME_LEVEL_DEF; #endif + +#if defined(CPUARM) + evalFunctions(g_eeGeneral.customFn, globalFunctionsContext); + evalFunctions(g_model.customFn, modelFunctionsContext); +#else evalFunctions(); +#endif } //========== LIMITS =============== diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index e24fcfaf6..67b026438 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -406,6 +406,192 @@ PACK(typedef struct { int16_t spanPos; }) CalibData; + +enum Functions { + // first the functions which need a checkbox + FUNC_OVERRIDE_CHANNEL, + FUNC_TRAINER, + FUNC_INSTANT_TRIM, + FUNC_RESET, +#if defined(CPUARM) + FUNC_SET_TIMER, +#endif + FUNC_ADJUST_GVAR, +#if defined(CPUARM) + FUNC_VOLUME, + FUNC_RESERVE1, + FUNC_RESERVE2, + FUNC_RESERVE3, +#endif + + // then the other functions + FUNC_FIRST_WITHOUT_ENABLE, + FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE, + FUNC_PLAY_TRACK, +#if !defined(CPUARM) + FUNC_PLAY_BOTH, +#endif + FUNC_PLAY_VALUE, +#if defined(CPUARM) + FUNC_PLAY_DIFF, + FUNC_PLAY_SCRIPT, + FUNC_RESERVE5, + FUNC_BACKGND_MUSIC, + FUNC_BACKGND_MUSIC_PAUSE, +#endif + FUNC_VARIO, + FUNC_HAPTIC, +#if !defined(PCBSTD) + FUNC_LOGS, +#endif + FUNC_BACKLIGHT, +#if defined(DEBUG) + FUNC_TEST, // should remain the last before MAX as not added in companion9x +#endif + FUNC_MAX +}; + +#if defined(OVERRIDE_CHANNEL_FUNCTION) + #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE) +#else + #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL) +#endif + +#if defined(VOICE) + #define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE) +#else + #define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND) +#endif + +#if defined(CPUARM) + #define IS_PLAY_BOTH_FUNC(func) (0) + #define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME) +#else + #define IS_PLAY_BOTH_FUNC(func) ((func) == FUNC_PLAY_BOTH) + #define IS_VOLUME_FUNC(func) (0) +#endif + +#if defined(GVARS) + #define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR) +#else + #define IS_ADJUST_GV_FUNC(func) (0) +#endif + +#if defined(HAPTIC) + #define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC) +#else + #define IS_HAPTIC_FUNC(func) (0) +#endif + +#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func)) + +enum ResetFunctionParam { + FUNC_RESET_TIMER1, + FUNC_RESET_TIMER2, +#if defined(CPUARM) + FUNC_RESET_TIMER3, +#endif + FUNC_RESET_FLIGHT, +#if defined(FRSKY) + FUNC_RESET_TELEMETRY, +#endif +#if ROTARY_ENCODERS > 0 + FUNC_RESET_ROTENC1, +#endif +#if ROTARY_ENCODERS > 1 + FUNC_RESET_ROTENC2, +#endif + FUNC_RESET_PARAMS_COUNT, + FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1 +}; + +enum AdjustGvarFunctionParam { + FUNC_ADJUST_GVAR_CONSTANT, + FUNC_ADJUST_GVAR_SOURCE, + FUNC_ADJUST_GVAR_GVAR, + FUNC_ADJUST_GVAR_INC, +}; + +#if defined(CPUARM) +#if defined(PCBTARANIS) + #define LEN_CFN_NAME 8 + #define CFN_SPARE_TYPE int32_t +#else + #define LEN_CFN_NAME 6 + #define CFN_SPARE_TYPE int16_t +#endif +PACK(typedef struct t_CustomFunctionData { // Function Switches data + int8_t swtch; + uint8_t func; + PACK(union { + PACK(struct { + char name[LEN_CFN_NAME]; + }) play; + + PACK(struct { + int16_t val; + uint8_t mode; + uint8_t param; + CFN_SPARE_TYPE spare2; + }) all; + + PACK(struct { + int32_t val1; + CFN_SPARE_TYPE val2; + }) clear; + }); + uint8_t active; +}) CustomFunctionData; +#define CFN_EMPTY(p) (!(p)->swtch) +#define CFN_SWITCH(p) ((p)->swtch) +#define CFN_FUNC(p) ((p)->func) +#define CFN_ACTIVE(p) ((p)->active) +#define CFN_CH_INDEX(p) ((p)->all.param) +#define CFN_GVAR_INDEX(p) ((p)->all.param) +#define CFN_TIMER_INDEX(p) ((p)->all.param) +#define CFN_PLAY_REPEAT(p) ((p)->active) +#define CFN_PLAY_REPEAT_MUL 1 +#define CFN_PLAY_REPEAT_NOSTART 0xFF +#define CFN_GVAR_MODE(p) ((p)->all.mode) +#define CFN_PARAM(p) ((p)->all.val) +#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0) +#define CFN_GVAR_CST_MAX GVAR_LIMIT +#else +PACK(typedef struct t_CustomFunctionData { + PACK(union { + PACK(struct { + int16_t swtch:6; + uint16_t func:4; + uint16_t mode:2; + uint16_t param:3; + uint16_t active:1; + }) gvar; + + PACK(struct { + int16_t swtch:6; + uint16_t func:4; + uint16_t param:4; + uint16_t spare:1; + uint16_t active:1; + }) all; + }); + uint8_t value; +}) CustomFunctionData; +#define CFN_SWITCH(p) ((p)->all.swtch) +#define CFN_FUNC(p) ((p)->all.func) +#define CFN_ACTIVE(p) ((p)->all.active) +#define CFN_CH_INDEX(p) ((p)->all.param) +#define CFN_TIMER_INDEX(p) ((p)->all.param) +#define CFN_GVAR_INDEX(p) ((p)->gvar.param) +#define CFN_PLAY_REPEAT(p) ((p)->all.param) +#define CFN_PLAY_REPEAT_MUL 10 +#define CFN_GVAR_MODE(p) ((p)->gvar.mode) +#define CFN_PARAM(p) ((p)->value) +#define CFN_RESET(p) ((p)->all.active = 0, CFN_PARAM(p) = 0) +#define CFN_GVAR_CST_MAX 125 +#endif + + #if defined(PCBSTD) #define N_PCBSTD_FIELD(x) #else @@ -466,6 +652,8 @@ PACK(typedef struct t_EEGeneral { swstate_t switchUnlockStates; + ARM_FIELD(CustomFunctionData customFn[NUM_CFN]) + }) EEGeneral; #define SWITCHES_DELAY() uint8_t(15+g_eeGeneral.switchesDelay) @@ -819,190 +1007,6 @@ PACK(typedef struct t_LogicalSwitchData { // Logical Switches data }) LogicalSwitchData; #endif -enum Functions { - // first the functions which need a checkbox - FUNC_OVERRIDE_CHANNEL, - FUNC_TRAINER, - FUNC_INSTANT_TRIM, - FUNC_RESET, -#if defined(CPUARM) - FUNC_SET_TIMER, -#endif - FUNC_ADJUST_GVAR, -#if defined(CPUARM) - FUNC_VOLUME, - FUNC_RESERVE1, - FUNC_RESERVE2, - FUNC_RESERVE3, -#endif - - // then the other functions - FUNC_FIRST_WITHOUT_ENABLE, - FUNC_PLAY_SOUND = FUNC_FIRST_WITHOUT_ENABLE, - FUNC_PLAY_TRACK, -#if !defined(CPUARM) - FUNC_PLAY_BOTH, -#endif - FUNC_PLAY_VALUE, -#if defined(CPUARM) - FUNC_PLAY_DIFF, - FUNC_PLAY_SCRIPT, - FUNC_RESERVE5, - FUNC_BACKGND_MUSIC, - FUNC_BACKGND_MUSIC_PAUSE, -#endif - FUNC_VARIO, - FUNC_HAPTIC, -#if !defined(PCBSTD) - FUNC_LOGS, -#endif - FUNC_BACKLIGHT, -#if defined(DEBUG) - FUNC_TEST, // should remain the last before MAX as not added in companion9x -#endif - FUNC_MAX -}; - -#if defined(OVERRIDE_CHANNEL_FUNCTION) - #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE) -#else - #define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE && (func) != FUNC_OVERRIDE_CHANNEL) -#endif - -#if defined(VOICE) - #define IS_PLAY_FUNC(func) ((func) >= FUNC_PLAY_SOUND && func <= FUNC_PLAY_VALUE) -#else - #define IS_PLAY_FUNC(func) ((func) == FUNC_PLAY_SOUND) -#endif - -#if defined(CPUARM) - #define IS_PLAY_BOTH_FUNC(func) (0) - #define IS_VOLUME_FUNC(func) ((func) == FUNC_VOLUME) -#else - #define IS_PLAY_BOTH_FUNC(func) ((func) == FUNC_PLAY_BOTH) - #define IS_VOLUME_FUNC(func) (0) -#endif - -#if defined(GVARS) - #define IS_ADJUST_GV_FUNC(func) ((func) == FUNC_ADJUST_GVAR) -#else - #define IS_ADJUST_GV_FUNC(func) (0) -#endif - -#if defined(HAPTIC) - #define IS_HAPTIC_FUNC(func) ((func) == FUNC_HAPTIC) -#else - #define IS_HAPTIC_FUNC(func) (0) -#endif - -#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func)) - -enum ResetFunctionParam { - FUNC_RESET_TIMER1, - FUNC_RESET_TIMER2, -#if defined(CPUARM) - FUNC_RESET_TIMER3, -#endif - FUNC_RESET_FLIGHT, -#if defined(FRSKY) - FUNC_RESET_TELEMETRY, -#endif -#if ROTARY_ENCODERS > 0 - FUNC_RESET_ROTENC1, -#endif -#if ROTARY_ENCODERS > 1 - FUNC_RESET_ROTENC2, -#endif - FUNC_RESET_PARAMS_COUNT, - FUNC_RESET_PARAM_LAST = FUNC_RESET_PARAMS_COUNT-1 -}; - -enum AdjustGvarFunctionParam { - FUNC_ADJUST_GVAR_CONSTANT, - FUNC_ADJUST_GVAR_SOURCE, - FUNC_ADJUST_GVAR_GVAR, - FUNC_ADJUST_GVAR_INC, -}; - -#if defined(CPUARM) -#if defined(PCBTARANIS) - #define LEN_CFN_NAME 8 - #define CFN_SPARE_TYPE int32_t -#else - #define LEN_CFN_NAME 6 - #define CFN_SPARE_TYPE int16_t -#endif -PACK(typedef struct t_CustomFnData { // Function Switches data - int8_t swtch; - uint8_t func; - PACK(union { - PACK(struct { - char name[LEN_CFN_NAME]; - }) play; - - PACK(struct { - int16_t val; - uint8_t mode; - uint8_t param; - CFN_SPARE_TYPE spare2; - }) all; - - PACK(struct { - int32_t val1; - CFN_SPARE_TYPE val2; - }) clear; - }); - uint8_t active; -}) CustomFnData; -#define CFN_EMPTY(p) (!(p)->swtch) -#define CFN_SWITCH(p) ((p)->swtch) -#define CFN_FUNC(p) ((p)->func) -#define CFN_ACTIVE(p) ((p)->active) -#define CFN_CH_INDEX(p) ((p)->all.param) -#define CFN_GVAR_INDEX(p) ((p)->all.param) -#define CFN_TIMER_INDEX(p) ((p)->all.param) -#define CFN_PLAY_REPEAT(p) ((p)->active) -#define CFN_PLAY_REPEAT_MUL 1 -#define CFN_PLAY_REPEAT_NOSTART 0xFF -#define CFN_GVAR_MODE(p) ((p)->all.mode) -#define CFN_PARAM(p) ((p)->all.val) -#define CFN_RESET(p) ((p)->active=0, (p)->clear.val1=0, (p)->clear.val2=0) -#define CFN_GVAR_CST_MAX GVAR_LIMIT -#else -PACK(typedef struct t_CustomFnData { - PACK(union { - PACK(struct { - int16_t swtch:6; - uint16_t func:4; - uint16_t mode:2; - uint16_t param:3; - uint16_t active:1; - }) gvar; - - PACK(struct { - int16_t swtch:6; - uint16_t func:4; - uint16_t param:4; - uint16_t spare:1; - uint16_t active:1; - }) all; - }); - uint8_t value; -}) CustomFnData; -#define CFN_SWITCH(p) ((p)->all.swtch) -#define CFN_FUNC(p) ((p)->all.func) -#define CFN_ACTIVE(p) ((p)->all.active) -#define CFN_CH_INDEX(p) ((p)->all.param) -#define CFN_TIMER_INDEX(p) ((p)->all.param) -#define CFN_GVAR_INDEX(p) ((p)->gvar.param) -#define CFN_PLAY_REPEAT(p) ((p)->all.param) -#define CFN_PLAY_REPEAT_MUL 10 -#define CFN_GVAR_MODE(p) ((p)->gvar.mode) -#define CFN_PARAM(p) ((p)->value) -#define CFN_RESET(p) ((p)->all.active = 0, CFN_PARAM(p) = 0) -#define CFN_GVAR_CST_MAX 125 -#endif - enum TelemetryUnit { UNIT_VOLTS, UNIT_AMPS, @@ -1832,7 +1836,7 @@ PACK(typedef struct { int8_t points[NUM_POINTS]; LogicalSwitchData logicalSw[NUM_LOGICAL_SWITCH]; - CustomFnData funcSw[NUM_CFN]; + CustomFunctionData customFn[NUM_CFN]; SwashRingData swashR; FlightModeData flightModeData[MAX_FLIGHT_MODES]; diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index be454fa3e..96acb9cbd 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -1666,503 +1666,16 @@ FORCEINLINE void evalTrims() } } -#if defined(DEBUG) -/* - * This is a test function for debugging purpose, you may insert there your code and compile with the option DEBUG=YES - */ -void testFunc() -{ -#ifdef SIMU - printf("testFunc\n"); fflush(stdout); -#endif -} -#endif - -MASK_FUNC_TYPE activeFunctions = 0; -MASK_CFN_TYPE activeFnSwitches = 0; -tmr10ms_t lastFunctionTime[NUM_CFN] = { 0 }; - -#if defined(VOICE) -PLAY_FUNCTION(playValue, uint8_t idx) -{ - if (IS_FAI_FORBIDDEN(idx)) - return; - - getvalue_t val = getValue(idx); - - switch (idx) { -#if defined(CPUARM) - case MIXSRC_FIRST_TELEM+TELEM_TX_TIME-1: - PLAY_DURATION(val*60, PLAY_TIME); - break; -#endif - case MIXSRC_FIRST_TELEM+TELEM_TX_VOLTAGE-1: - PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1); - break; - case MIXSRC_FIRST_TELEM+TELEM_TIMER1-1: - case MIXSRC_FIRST_TELEM+TELEM_TIMER2-1: -#if defined(CPUARM) - case MIXSRC_FIRST_TELEM+TELEM_TIMER3-1: -#endif - PLAY_DURATION(val, 0); - break; -#if defined(CPUARM) && defined(FRSKY) - case MIXSRC_FIRST_TELEM+TELEM_SWR-1: - PLAY_NUMBER(val, 0, 0); - break; -#endif -#if defined(FRSKY) - case MIXSRC_FIRST_TELEM+TELEM_RSSI_TX-1: - case MIXSRC_FIRST_TELEM+TELEM_RSSI_RX-1: - PLAY_NUMBER(val, 1+UNIT_DBM, 0); - break; - case MIXSRC_FIRST_TELEM+TELEM_MIN_A1-1: - case MIXSRC_FIRST_TELEM+TELEM_MIN_A2-1: -#if defined(CPUARM) - case MIXSRC_FIRST_TELEM+TELEM_MIN_A3-1: - case MIXSRC_FIRST_TELEM+TELEM_MIN_A4-1: -#endif - idx -= TELEM_MIN_A1-TELEM_A1; - // no break - case MIXSRC_FIRST_TELEM+TELEM_A1-1: - case MIXSRC_FIRST_TELEM+TELEM_A2-1: -#if defined(CPUARM) - case MIXSRC_FIRST_TELEM+TELEM_A3-1: - case MIXSRC_FIRST_TELEM+TELEM_A4-1: -#endif - if (TELEMETRY_STREAMING()) { - idx -= (MIXSRC_FIRST_TELEM+TELEM_A1-1); - uint8_t att = 0; - int16_t converted_value = div10_and_round(applyChannelRatio(idx, val));; - if (ANA_CHANNEL_UNIT(idx) < UNIT_RAW) { - att = PREC1; - } - PLAY_NUMBER(converted_value, 1+ANA_CHANNEL_UNIT(idx), att); - } - break; - case MIXSRC_FIRST_TELEM+TELEM_CELL-1: - case MIXSRC_FIRST_TELEM+TELEM_MIN_CELL-1: - PLAY_NUMBER(div10_and_round(val), 1+UNIT_VOLTS, PREC1); - break; - - case MIXSRC_FIRST_TELEM+TELEM_VFAS-1: - case MIXSRC_FIRST_TELEM+TELEM_CELLS_SUM-1: - case MIXSRC_FIRST_TELEM+TELEM_MIN_CELLS_SUM-1: - case MIXSRC_FIRST_TELEM+TELEM_MIN_VFAS-1: - PLAY_NUMBER(val, 1+UNIT_VOLTS, PREC1); - break; - - case MIXSRC_FIRST_TELEM+TELEM_CURRENT-1: - case MIXSRC_FIRST_TELEM+TELEM_MAX_CURRENT-1: - PLAY_NUMBER(val, 1+UNIT_AMPS, PREC1); - break; - - case MIXSRC_FIRST_TELEM+TELEM_ACCx-1: - case MIXSRC_FIRST_TELEM+TELEM_ACCy-1: - case MIXSRC_FIRST_TELEM+TELEM_ACCz-1: - PLAY_NUMBER(div10_and_round(val), 1+UNIT_G, PREC1); - break; - - case MIXSRC_FIRST_TELEM+TELEM_VSPEED-1: - PLAY_NUMBER(div10_and_round(val), 1+UNIT_METERS_PER_SECOND, PREC1); - break; - - case MIXSRC_FIRST_TELEM+TELEM_ASPEED-1: - case MIXSRC_FIRST_TELEM+TELEM_MAX_ASPEED-1: - PLAY_NUMBER(val/10, 1+UNIT_KTS, 0); - break; - - case MIXSRC_FIRST_TELEM+TELEM_CONSUMPTION-1: - PLAY_NUMBER(val, 1+UNIT_MAH, 0); - break; - - case MIXSRC_FIRST_TELEM+TELEM_POWER-1: - PLAY_NUMBER(val, 1+UNIT_WATTS, 0); - break; - - case MIXSRC_FIRST_TELEM+TELEM_ALT-1: -#if defined(PCBTARANIS) - PLAY_NUMBER(div10_and_round(val), 1+UNIT_DIST, PREC1); - break; -#endif - case MIXSRC_FIRST_TELEM+TELEM_MIN_ALT-1: - case MIXSRC_FIRST_TELEM+TELEM_MAX_ALT-1: -#if defined(WS_HOW_HIGH) - if (IS_IMPERIAL_ENABLE() && IS_USR_PROTO_WS_HOW_HIGH()) - PLAY_NUMBER(val, 1+UNIT_FEET, 0); - else -#endif - PLAY_NUMBER(val, 1+UNIT_DIST, 0); - break; - - case MIXSRC_FIRST_TELEM+TELEM_RPM-1: - case MIXSRC_FIRST_TELEM+TELEM_MAX_RPM-1: - { - getvalue_t rpm = val; - if (rpm > 100) - rpm = 10 * div10_and_round(rpm); - if (rpm > 1000) - rpm = 10 * div10_and_round(rpm); - PLAY_NUMBER(rpm, 1+UNIT_RPMS, 0); - break; - } - - case MIXSRC_FIRST_TELEM+TELEM_HDG-1: - PLAY_NUMBER(val, 1+UNIT_HDG, 0); - break; - - default: - { - uint8_t unit = 1; - if (idx < MIXSRC_GVAR1) - val = calcRESXto100(val); - if (idx >= MIXSRC_FIRST_TELEM+TELEM_ALT-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_GPSALT-1) - unit = idx - (MIXSRC_FIRST_TELEM+TELEM_ALT-1); - else if (idx >= MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1 && idx <= MIXSRC_FIRST_TELEM+TELEM_MAX_DIST-1) - unit = 3 + idx - (MIXSRC_FIRST_TELEM+TELEM_MAX_T1-1); - - unit = pgm_read_byte(bchunit_ar+unit); - PLAY_NUMBER(val, unit == UNIT_RAW ? 0 : unit+1, 0); - break; - } -#else - default: - { - PLAY_NUMBER(val, 0, 0); - break; - } -#endif - } -} -#endif - #if !defined(PCBSTD) uint8_t mSwitchDuration[1+NUM_ROTARY_ENCODERS] = { 0 }; #define CFN_PRESSLONG_DURATION 100 #endif #if defined(CPUARM) -#define VOLUME_HYSTERESIS 10 // how much must a input value change to actually be considered for new volume setting uint8_t currentSpeakerVolume = 255; uint8_t requiredSpeakerVolume; -getvalue_t requiredSpeakerVolumeRawLast = 1024 + 1; //initial value must be outside normal range - -inline void playCustomFunctionFile(CustomFnData *sd, uint8_t id) -{ - if (sd->play.name[0] != '\0') { - char filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)+sizeof(SOUNDS_EXT)] = SOUNDS_PATH "/"; - strncpy(filename+SOUNDS_PATH_LNG_OFS, currentLanguagePack->id, 2); - strncpy(filename+sizeof(SOUNDS_PATH), sd->play.name, sizeof(sd->play.name)); - filename[sizeof(SOUNDS_PATH)+sizeof(sd->play.name)] = '\0'; - strcat(filename+sizeof(SOUNDS_PATH), SOUNDS_EXT); - PLAY_FILE(filename, sd->func==FUNC_BACKGND_MUSIC ? PLAY_BACKGROUND : 0, id); - } -} #endif -void evalFunctions() -{ - MASK_FUNC_TYPE newActiveFunctions = 0; - MASK_CFN_TYPE newActiveFnSwitches = 0; - -#if defined(ROTARY_ENCODERS) && defined(GVARS) - static rotenc_t rePreviousValues[ROTARY_ENCODERS]; -#endif - -#if defined(OVERRIDE_CHANNEL_FUNCTION) - for (uint8_t i=0; i 0) { - mask = (1<<(CFN_CH_INDEX(sd)-1)); - } - newActiveFunctions |= mask; - break; - } - - case FUNC_INSTANT_TRIM: - newActiveFunctions |= (1 << FUNCTION_INSTANT_TRIM); - if (!isFunctionActive(FUNCTION_INSTANT_TRIM)) { - if (g_menuStack[0] == menuMainView -#if defined(FRSKY) - || g_menuStack[0] == menuTelemetryFrsky -#endif -#if defined(PCBTARANIS) - || g_menuStack[0] == menuMainViewChannelsMonitor - || g_menuStack[0] == menuChannelsView -#endif - ) { - instantTrim(); - } - } - break; - - case FUNC_RESET: - switch (CFN_PARAM(sd)) { - case FUNC_RESET_TIMER1: - case FUNC_RESET_TIMER2: -#if defined(CPUARM) - case FUNC_RESET_TIMER3: -#endif - timerReset(CFN_PARAM(sd)); - break; - case FUNC_RESET_FLIGHT: - flightReset(); - break; -#if defined(FRSKY) - case FUNC_RESET_TELEMETRY: - telemetryReset(); - break; -#endif -#if ROTARY_ENCODERS > 0 - case FUNC_RESET_ROTENC1: -#if ROTARY_ENCODERS > 1 - case FUNC_RESET_ROTENC2: -#endif - g_rotenc[CFN_PARAM(sd)-FUNC_RESET_ROTENC1] = 0; - break; -#endif - } - break; - -#if defined(CPUARM) - case FUNC_SET_TIMER: - { - TimerState & timerState = timersStates[CFN_TIMER_INDEX(sd)]; - timerState.state = TMR_OFF; // is changed to RUNNING dep from mode - timerState.val = CFN_PARAM(sd); - timerState.val_10ms = 0 ; - break; - } -#endif - -#if defined(GVARS) - case FUNC_ADJUST_GVAR: - if (CFN_GVAR_MODE(sd) == 0) { - SET_GVAR(CFN_GVAR_INDEX(sd), CFN_PARAM(sd), mixerCurrentFlightMode); - } - else if (CFN_GVAR_MODE(sd) == 2) { - SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_PARAM(sd), mixerCurrentFlightMode), mixerCurrentFlightMode); - } - else if (CFN_GVAR_MODE(sd) == 3) { - if (!(activeFnSwitches & switch_mask)) { - SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(sd))) + (CFN_PARAM(sd) ? +1 : -1), mixerCurrentFlightMode); - } - } - else if (CFN_PARAM(sd) >= MIXSRC_TrimRud && CFN_PARAM(sd) <= MIXSRC_TrimAil) { - trimGvar[CFN_PARAM(sd)-MIXSRC_TrimRud] = CFN_GVAR_INDEX(sd); - } -#if defined(ROTARY_ENCODERS) - else if (CFN_PARAM(sd) >= MIXSRC_REa && CFN_PARAM(sd) < MIXSRC_TrimRud) { - int8_t scroll = rePreviousValues[CFN_PARAM(sd)-MIXSRC_REa] - (g_rotenc[CFN_PARAM(sd)-MIXSRC_REa] / ROTARY_ENCODER_GRANULARITY); - if (scroll) { - SET_GVAR(CFN_GVAR_INDEX(sd), GVAR_VALUE(CFN_GVAR_INDEX(sd), getGVarFlightPhase(mixerCurrentFlightMode, CFN_GVAR_INDEX(sd))) + scroll, mixerCurrentFlightMode); - } - } -#endif - else { - SET_GVAR(CFN_GVAR_INDEX(sd), calcRESXto100(getValue(CFN_PARAM(sd))), mixerCurrentFlightMode); - } - break; -#endif - -#if defined(CPUARM) && defined(SDCARD) - case FUNC_VOLUME: - { - getvalue_t raw = getValue(CFN_PARAM(sd)); - //only set volume if input changed more than hysteresis - if (abs(requiredSpeakerVolumeRawLast - raw) > VOLUME_HYSTERESIS) { - requiredSpeakerVolumeRawLast = raw; - } - requiredSpeakerVolume = ((1024 + requiredSpeakerVolumeRawLast) * VOLUME_LEVEL_MAX) / 2048; - break; - } -#endif - -#if defined(CPUARM) && defined(SDCARD) - case FUNC_PLAY_SOUND: - case FUNC_PLAY_TRACK: - case FUNC_PLAY_VALUE: -#if defined(HAPTIC) - case FUNC_HAPTIC: -#endif - { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (!IS_SILENCE_PERIOD_ELAPSED() && repeatParam == CFN_PLAY_REPEAT_NOSTART) - lastFunctionTime[i] = tmr10ms; - if (!lastFunctionTime[i] || (repeatParam && repeatParam!=CFN_PLAY_REPEAT_NOSTART && (signed)(tmr10ms-lastFunctionTime[i])>=100*repeatParam)) { - if (!IS_PLAYING(i+1)) { - lastFunctionTime[i] = tmr10ms; - if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { - AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd)); - } - else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - PLAY_VALUE(CFN_PARAM(sd), i+1); - } -#if defined(HAPTIC) - else if (CFN_FUNC(sd) == FUNC_HAPTIC) { - haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd)); - } -#endif - else { - playCustomFunctionFile(sd, i+1); - } - } - } - break; - } - - case FUNC_BACKGND_MUSIC: - newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC); - if (!IS_PLAYING(i+1)) { - playCustomFunctionFile(sd, i+1); - } - break; - - case FUNC_BACKGND_MUSIC_PAUSE: - newActiveFunctions |= (1 << FUNCTION_BACKGND_MUSIC_PAUSE); - break; - -#elif defined(VOICE) - case FUNC_PLAY_SOUND: - case FUNC_PLAY_TRACK: - case FUNC_PLAY_BOTH: - case FUNC_PLAY_VALUE: - { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (!lastFunctionTime[i] || (CFN_FUNC(sd)==FUNC_PLAY_BOTH && active!=(bool)(activeFnSwitches&switch_mask)) || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { - lastFunctionTime[i] = tmr10ms; - uint8_t param = CFN_PARAM(sd); - if (CFN_FUNC(sd) == FUNC_PLAY_SOUND) { - AUDIO_PLAY(AU_FRSKY_FIRST+param); - } - else if (CFN_FUNC(sd) == FUNC_PLAY_VALUE) { - PLAY_VALUE(param, i+1); - } - else { -#if defined(GVARS) - if (CFN_FUNC(sd) == FUNC_PLAY_TRACK && param > 250) - param = GVAR_VALUE(param-251, getGVarFlightPhase(mixerCurrentFlightMode, param-251)); -#endif - PUSH_CUSTOM_PROMPT(active ? param : param+1, i+1); - } - } - if (!active) { - // PLAY_BOTH would change activeFnSwitches otherwise - switch_mask = 0; - } - break; - } -#else - case FUNC_PLAY_SOUND: - { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (!lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { - lastFunctionTime[i] = tmr10ms; - AUDIO_PLAY(AU_FRSKY_FIRST+CFN_PARAM(sd)); - } - break; - } -#endif - -#if defined(FRSKY) && defined(VARIO) - case FUNC_VARIO: - newActiveFunctions |= (1 << FUNCTION_VARIO); - break; -#endif - -#if defined(HAPTIC) && !defined(CPUARM) - case FUNC_HAPTIC: - { - tmr10ms_t tmr10ms = get_tmr10ms(); - uint8_t repeatParam = CFN_PLAY_REPEAT(sd); - if (!lastFunctionTime[i] || (repeatParam && (signed)(tmr10ms-lastFunctionTime[i])>=1000*repeatParam)) { - lastFunctionTime[i] = tmr10ms; - haptic.event(AU_FRSKY_LAST+CFN_PARAM(sd)); - } - break; - } -#endif - -#if defined(SDCARD) - case FUNC_LOGS: - if (CFN_PARAM(sd)) { - newActiveFunctions |= (1 << FUNCTION_LOGS); - logDelay = CFN_PARAM(sd); - } - break; -#endif - - case FUNC_BACKLIGHT: - newActiveFunctions |= (1 << FUNCTION_BACKLIGHT); - break; - -#if defined(DEBUG) - case FUNC_TEST: - testFunc(); - break; -#endif - } - - newActiveFnSwitches |= switch_mask; - } - else { - lastFunctionTime[i] = 0; - } - } - } - - activeFnSwitches = newActiveFnSwitches; - activeFunctions = newActiveFunctions; - -#if defined(ROTARY_ENCODERS) && defined(GVARS) - for (uint8_t i=0; i off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw int16_t prev; @@ -1237,7 +1234,7 @@ PACK(typedef struct t_SwOn { #define DELAY_POS_SHIFT 10 #define DELAY_POS_MARGIN 0 #define delayval_t int8_t -PACK(typedef struct t_SwOn { +PACK(typedef struct { uint16_t delay:10; int16_t now:2; // timer trigger source -> off, abs, stk, stk%, sw/!sw, !m_sw/!m_sw int16_t prev:2; @@ -1308,14 +1305,41 @@ enum FunctionsActive { #define VARIO_REPEAT_ZERO 500/*ms*/ #define VARIO_REPEAT_MAX 80/*ms*/ -extern MASK_FUNC_TYPE activeFunctions; -extern MASK_CFN_TYPE activeFnSwitches; -extern tmr10ms_t lastFunctionTime[NUM_CFN]; +typedef struct { + MASK_FUNC_TYPE activeFunctions; + MASK_CFN_TYPE activeSwitches; + tmr10ms_t lastFunctionTime[NUM_CFN]; + inline bool isFuunctionActive(uint8_t func) + { + return activeFunctions & ((MASK_FUNC_TYPE)1 << func); + } + + void reset() + { + memclear(this, sizeof(*this)); + } +} CustomFunctionsContext; + +#if defined(CPUARM) +extern CustomFunctionsContext modelFunctionsContext; +extern CustomFunctionsContext globalFunctionsContext; inline bool isFunctionActive(uint8_t func) { - return activeFunctions & ((uint8_t)1 << func); + return globalFunctionsContext.isFuunctionActive(func) || modelFunctionsContext.isFuunctionActive(func); } +void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext & functionsContext); +inline void customFunctionsReset() +{ + globalFunctionsContext.reset(); + modelFunctionsContext.reset(); +} +#else +extern CustomFunctionsContext modelFunctionsContext; +#define isFunctionActive(func) modelFunctionsContext.isFuunctionActive(func) +void evalFunctions(); +#define customFunctionsReset() modelFunctionsContext.reset() +#endif #if defined(ROTARY_ENCODERS) // Global rotary encoder registers @@ -1324,6 +1348,8 @@ inline bool isFunctionActive(uint8_t func) extern volatile rotenc_t g_rotenc[1]; #endif +#include "gui/menus.h" + #if defined (FRSKY) // FrSky Telemetry #include "telemetry/frsky.h" diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index 7a09e0818..23e150493 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -295,6 +295,7 @@ const pm_char STR_MENUDATEANDTIME[] PROGMEM = TR_MENUDATEANDTIME; #endif const pm_char STR_MENUTRAINER[] PROGMEM = TR_MENUTRAINER; +const pm_char STR_MENUGLOBALFUNCS[] PROGMEM = TR_MENUGLOBALFUNCS; const pm_char STR_MENUVERSION[] PROGMEM = TR_MENUVERSION; const pm_char STR_MENUDIAG[] PROGMEM = TR_MENUDIAG; const pm_char STR_MENUANA[] PROGMEM = TR_MENUANA; diff --git a/radio/src/translations.h b/radio/src/translations.h index ce06655e4..99a15a148 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -456,6 +456,7 @@ extern const pm_char STR_TRIMS2OFFSETS[]; extern const pm_char STR_MENURADIOSETUP[]; extern const pm_char STR_MENUDATEANDTIME[]; extern const pm_char STR_MENUTRAINER[]; +extern const pm_char STR_MENUGLOBALFUNCS[]; extern const pm_char STR_MENUVERSION[]; extern const pm_char STR_MENUDIAG[]; extern const pm_char STR_MENUANA[]; diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index 5602a6406..f75792bbd 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -664,6 +664,7 @@ #define TR_MENURADIOSETUP "NASTAVENÍ RÁDIA" #define TR_MENUDATEANDTIME "DATUM A čAS" #define TR_MENUTRAINER "TRENÉR" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERZE" #define TR_MENUDIAG "DIAG" #define TR_MENUANA "ANALOGY" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index ae9992e9d..907993a6c 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -667,6 +667,7 @@ #define TR_MENURADIOSETUP TR("SENDER-EINSTELLEN","SENDER-GRUNDEINSTELLUNGEN") #define TR_MENUDATEANDTIME "DATUM UND ZEIT" #define TR_MENUTRAINER TR("LEHRER/SCHÜLER","LEHRER/SCHÜLER") +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSION" #define TR_MENUDIAG TR("Schalt.","Schalter-Test") #define TR_MENUANA "Analog-Test" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index 9e4649c13..2648ce22c 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -671,6 +671,7 @@ #define TR_MENURADIOSETUP "RADIO SETUP" #define TR_MENUDATEANDTIME "DATE AND TIME" #define TR_MENUTRAINER "TRAINER" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSION" #define TR_MENUDIAG TR("SWITCHES","SWITCH TEST") #define TR_MENUANA TR("ANAS","ANALOG INPUTS") diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index cd07180b7..f9365bb2c 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "CONFIGURACION" #define TR_MENUDATEANDTIME "FECHA Y HORA" #define TR_MENUTRAINER "APRENDIZ" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSION" #define TR_MENUDIAG TR("INTERUPTS", "TEST INTERUP.") #define TR_MENUANA TR("ANAS", "ENTRADAS ANALOG") diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 1e2171cff..5c47bbe9f 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "RADIO SETUP" #define TR_MENUDATEANDTIME "DATE AND TIME" #define TR_MENUTRAINER "TRAINER" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSION" #define TR_MENUDIAG TR("SWITCHES","SWITCH TEST") #define TR_MENUANA TR("ANAS","ANALOG INPUTS") diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 077eab273..3cd8d2356 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "CONFIG RADIO" #define TR_MENUDATEANDTIME "DATE ET HEURE" #define TR_MENUTRAINER "ECOLAGE" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSION" #define TR_MENUDIAG TR("INTERS","TEST INTERRUPTEURS") #define TR_MENUANA TR("ANAS","ENTREES ANALOGIQUES") diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 5b942c041..b80ae46c0 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "CONFIGURATX" #define TR_MENUDATEANDTIME "DATA E ORA" #define TR_MENUTRAINER "MAESTRO/ALLIEVO" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSIONE" #define TR_MENUDIAG "DIAG" #define TR_MENUANA "ANAS" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 35107e7c0..2a505f44b 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "USTAWIENIA RADIA" #define TR_MENUDATEANDTIME "DATA I CZAS" #define TR_MENUTRAINER "TRENER" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "WERSJA" #define TR_MENUDIAG TR("PRZEŁ","TEST PRZEŁ") #define TR_MENUANA TR("WE-ANA","WEJŚCIA ANALOG.") diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 06d540e51..9519bfd21 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "AJUSTAR RADIO" #define TR_MENUDATEANDTIME "DATA E HORA" #define TR_MENUTRAINER "TRAINER" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSAO" #define TR_MENUDIAG "DIAGNOST" #define TR_MENUANA "ANALOGICOS" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index eeb7dacc9..f30e151c9 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -660,6 +660,7 @@ #define TR_MENURADIOSETUP "INSTÄLLNINGAR" #define TR_MENUDATEANDTIME "DAG OCH TID" #define TR_MENUTRAINER "TRAINER (PPM IN)" +#define TR_MENUGLOBALFUNCS "GLOBAL FUNCTIONS" #define TR_MENUVERSION "VERSION" #define TR_MENUDIAG TR("BRYTARE","TEST AV BRYTARE") #define TR_MENUANA "ANALOGA VÄRDEN"
"+tr("L")+QString("%1