diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 512dd6e7003..24c31279b9b 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -22,10 +22,10 @@ #include "boards.h" #include "macros.h" #include "compounditemmodels.h" -#include "moduledata.h" #include "helpers.h" #include "boardfactories.h" #include "generalsettings.h" +#include "modeldata.h" // TODO remove all those constants // Update: These are now all only used within this class. @@ -330,7 +330,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case FunctionSwitchGroups: if (getCapability(board, FunctionSwitches)) { - return IS_RADIOMASTER_GX12(board) ? 4 : 3; + return IS_RADIOMASTER_GX12(board) ? CPN_MAX_CUSTOMSWITCH_GROUPS : 3; } return 0; diff --git a/companion/src/firmwares/customisation_data.cpp b/companion/src/firmwares/customisation_data.cpp index 14df45739d6..deda4a21cb9 100644 --- a/companion/src/firmwares/customisation_data.cpp +++ b/companion/src/firmwares/customisation_data.cpp @@ -29,12 +29,28 @@ ZoneOptionValue::ZoneOptionValue() { - unsignedValue = 0; - signedValue = 0; - boolValue = 0; - stringValue.clear(); - sourceValue.clear(); - colorValue = 0; + clear(); +} + +ZoneOptionValue::ZoneOptionValue(const ZoneOptionValue & src) +{ + copy(src); +} + +ZoneOptionValue & ZoneOptionValue::operator=(const ZoneOptionValue & src) +{ + copy(src); + return *this; +} + +void ZoneOptionValue::copy(const ZoneOptionValue & src) +{ + unsignedValue = src.unsignedValue; + signedValue = src.signedValue; + boolValue = src.boolValue; + stringValue = src.stringValue; + sourceValue = src.sourceValue; + colorValue = src.colorValue; } bool ZoneOptionValue::isEmpty() const @@ -43,9 +59,14 @@ bool ZoneOptionValue::isEmpty() const stringValue.empty() && sourceValue.toValue() == 0; } -ZoneOptionValueTyped::ZoneOptionValueTyped() +void ZoneOptionValue::clear() { - type = ZOV_Unsigned; + unsignedValue = 0; + signedValue = 0; + boolValue = 0; + stringValue.clear(); + sourceValue.clear(); + colorValue = 0; } inline void setZoneOptionValue(ZoneOptionValue& zov, bool value) @@ -107,31 +128,108 @@ inline const char * zoneOptionValueEnumToString(ZoneOptionValueEnum zovenum) { } } -static const ZoneOptionValueTyped zero_widget_option = {}; +ZoneOptionValueTyped::ZoneOptionValueTyped() +{ + clear(); +} bool ZoneOptionValueTyped::isEmpty() const { return type == ZOV_Unsigned && value.isEmpty(); } +void ZoneOptionValueTyped::clear() +{ + type = ZOV_Unsigned; + value.clear(); +} + +void WidgetPersistentData::clear() +{ + for (int i = 0; i < MAX_WIDGET_OPTIONS; i += 1) + options[i].clear(); +} + +ZonePersistentData::ZonePersistentData(const ZonePersistentData & src) +{ + copy(src); +} + +ZonePersistentData & ZonePersistentData::operator=(const ZonePersistentData & src) +{ + copy(src); + return *this; +} + +void ZonePersistentData::copy(const ZonePersistentData & src) +{ + widgetName = src.widgetName; + widgetData = src.widgetData; +} + bool ZonePersistentData::isEmpty() const { return widgetName.empty(); } +void ZonePersistentData::clear() +{ + widgetName.clear(); + widgetData.clear(); +} + +RadioLayout::CustomScreenData::CustomScreenData(const RadioLayout::CustomScreenData & src) +{ + copy(src); +} + +RadioLayout::CustomScreenData & RadioLayout::CustomScreenData::operator=(const RadioLayout::CustomScreenData & src) +{ + copy(src); + return *this; +} + +void RadioLayout::CustomScreenData::copy(const RadioLayout::CustomScreenData & src) +{ + layoutId = src.layoutId; + layoutPersistentData = src.layoutPersistentData; +} + bool RadioLayout::CustomScreenData::isEmpty() const { return layoutId.empty(); } +void RadioLayout::CustomScreenData::clear() +{ + layoutId.clear(); + layoutPersistentData.clear(); +} + +RadioLayout::CustomScreens::CustomScreens(const RadioLayout::CustomScreens & src) +{ + copy(src); +} + +RadioLayout::CustomScreens & RadioLayout::CustomScreens::operator=(const RadioLayout::CustomScreens & src) +{ + copy(src); + return *this; +} + +void RadioLayout::CustomScreens::copy(const RadioLayout::CustomScreens & src) +{ + for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) + customScreenData[i] = src.customScreenData[i]; +} + void RadioLayout::CustomScreens::clear() { - for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) { - customScreenData[i] = CustomScreenData(); - } + for (int i = 0; i < MAX_CUSTOM_SCREENS; i++) + customScreenData[i].clear(); } -void RadioLayout::init(const char* layoutId, CustomScreens& customScreens) +void RadioLayout::init(const std::string layoutId, CustomScreens& customScreens) { customScreens.clear(); diff --git a/companion/src/firmwares/customisation_data.h b/companion/src/firmwares/customisation_data.h index f26b4321e57..2d01653b488 100644 --- a/companion/src/firmwares/customisation_data.h +++ b/companion/src/firmwares/customisation_data.h @@ -60,6 +60,11 @@ struct ZoneOptionValue // union in radio/src/datastructs.h unsigned int colorValue; ZoneOptionValue(); + ZoneOptionValue(const ZoneOptionValue & src); + ZoneOptionValue & operator=(const ZoneOptionValue & src); + + void clear(); + void copy(const ZoneOptionValue & src); bool isEmpty() const; }; @@ -111,6 +116,7 @@ struct ZoneOptionValueTyped ZoneOptionValue value; ZoneOptionValueTyped(); + void clear(); bool isEmpty() const; }; @@ -118,6 +124,7 @@ struct WidgetPersistentData { ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS]; WidgetPersistentData() {} + void clear(); }; struct ZonePersistentData { @@ -125,6 +132,10 @@ struct ZonePersistentData { WidgetPersistentData widgetData; ZonePersistentData() {} + ZonePersistentData(const ZonePersistentData & src); + ZonePersistentData & operator=(const ZonePersistentData & src); + void clear(); + void copy(const ZonePersistentData & src); bool isEmpty() const; }; @@ -134,6 +145,14 @@ struct WidgetsContainerPersistentData { ZoneOptionValueTyped options[O]; WidgetsContainerPersistentData() {} + void clear() { + for (int i = 0; i < N; i++) { + zones[i].clear(); + } + for (int i = 0; i < O; i++) { + options[i].clear(); + } + } }; typedef WidgetsContainerPersistentData @@ -152,14 +171,24 @@ class RadioLayout LayoutPersistentData layoutPersistentData; CustomScreenData() {} + CustomScreenData(const CustomScreenData & src); + CustomScreenData & operator=(const CustomScreenData & src); + + void clear(); + void copy(const CustomScreenData & src); bool isEmpty() const; }; struct CustomScreens { CustomScreenData customScreenData[MAX_CUSTOM_SCREENS]; + CustomScreens() {} + CustomScreens(const CustomScreens & src); + CustomScreens & operator=(const CustomScreens & src); + void clear(); + void copy(const CustomScreens & src); }; - static void init(const char * layoutId, CustomScreens & customScreens); + static void init(const std::string layoutId, CustomScreens & customScreens); }; diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index 07129cb1e8e..c1db7a7b423 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -984,12 +984,12 @@ struct convert { }; template <> -struct convert { - static Node encode(const customSwitch& rhs); - static bool decode(const Node& node, customSwitch& rhs); +struct convert { + static Node encode(const CustomSwitchData& rhs); + static bool decode(const Node& node, CustomSwitchData& rhs); }; -Node convert::encode(const customSwitch& rhs) +Node convert::encode(const CustomSwitchData& rhs) { Node node; node["type"] = cfsSwitchConfig << rhs.type; @@ -1006,7 +1006,7 @@ Node convert::encode(const customSwitch& rhs) return node; } -bool convert::decode(const Node& node, customSwitch& rhs) +bool convert::decode(const Node& node, CustomSwitchData& rhs) { if (!node.IsMap()) return false; @@ -1254,7 +1254,7 @@ Node convert::encode(const ModelData& rhs) if (topbarData && topbarData.IsMap()) { node["topbarData"] = topbarData; } - for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1) + for (int i = 0; i < MAX_TOPBAR_ZONES; i++) if (rhs.topbarWidgetWidth[i] > 0) node["topbarWidgetWidth"][std::to_string(i)]["val"] = (int)rhs.topbarWidgetWidth[i]; node["view"] = rhs.view; @@ -1265,14 +1265,17 @@ Node convert::encode(const ModelData& rhs) int funcSwCnt = Boards::getCapability(board, Board::FunctionSwitches); if (funcSwCnt) { - for (int i = 0; i < funcSwCnt; i += 1) { + for (int i = 0; i < funcSwCnt; i++) { int sw = Boards::getSwitchIndexForCFS(i); std::string tag = Boards::getSwitchYamlName(sw, BoardJson::YLT_CONFIG).toStdString(); node["customSwitches"][tag] = rhs.customSwitches[i]; } - for (int i = 1; i < 4; i += 1) { - node["cfsGroupOn"][std::to_string(i)]["v"] = rhs.cfsGroupOn[i]; + int funcSwGrps = Boards::getCapability(board, Board::FunctionSwitchGroups); + if (funcSwGrps) { + for (int i = 1; i <= funcSwGrps; i++) { + node["cfsGroupOn"][std::to_string(i)]["v"] = rhs.cfsGroupOn[i]; + } } } @@ -1559,7 +1562,7 @@ bool convert::decode(const Node& node, ModelData& rhs) rhs.customSwitches[i].group = v & 3; v >>= 2; } - for (int i = 0; i < 4; i += 1) { + for (int i = 0; i < CPN_MAX_CUSTOMSWITCH_GROUPS; i += 1) { rhs.cfsGroupOn[i] = v & 1; v >>= 1; } @@ -1601,8 +1604,8 @@ bool convert::decode(const Node& node, ModelData& rhs) } } } - int funcSwCnt = Boards::getCapability(board, Board::FunctionSwitches); if (node["customSwitches"]) { + int funcSwCnt = Boards::getCapability(board, Board::FunctionSwitches); for (int i = 0; i < funcSwCnt; i += 1) { int sw = Boards::getSwitchIndexForCFS(i); std::string tag = Boards::getSwitchYamlName(sw, BoardJson::YLT_CONFIG).toStdString(); @@ -1610,7 +1613,7 @@ bool convert::decode(const Node& node, ModelData& rhs) } } if (node["cfsGroupOn"]) { - for (int i = 1; i < 4; i += 1) { + for (int i = 1; i < CPN_MAX_CUSTOMSWITCH_GROUPS; i += 1) { if (node["cfsGroupOn"][std::to_string(i)]) { node["cfsGroupOn"][std::to_string(i)]["v"] >> rhs.cfsGroupOn[i]; } diff --git a/companion/src/firmwares/modeldata.cpp b/companion/src/firmwares/modeldata.cpp index 7060e68e1b0..8d8a7c9469a 100644 --- a/companion/src/firmwares/modeldata.cpp +++ b/companion/src/firmwares/modeldata.cpp @@ -39,15 +39,96 @@ ModelData::ModelData() ModelData::ModelData(const ModelData & src) { - *this = src; + copy(src); } -ModelData & ModelData::operator = (const ModelData & src) +ModelData & ModelData::operator=(const ModelData & src) { - memcpy(reinterpret_cast(this), &src, sizeof(ModelData)); + copy(src); return *this; } +void ModelData::copy(const ModelData & src) +{ + memcpy(&semver, &src.semver, sizeof(semver)); + used = src.used; + memcpy(&name, &src.name, sizeof(name)); + memcpy(&filename, &src.filename, sizeof(filename)); + memcpy(&labels, &src.labels, sizeof(labels)); + modelIndex = src.modelIndex; + modelUpdated = src.modelUpdated; + modelErrors = src.modelErrors; + memcpy(&timers[0], &src.timers[0], sizeof(timers[0]) * CPN_MAX_TIMERS); + noGlobalFunctions = src.noGlobalFunctions; + thrTrim = src.thrTrim; + trimInc = src.trimInc; + trimsDisplay = src.trimsDisplay; + disableThrottleWarning = src.disableThrottleWarning; + enableCustomThrottleWarning = src.enableCustomThrottleWarning; + customThrottleWarningPosition = src.customThrottleWarningPosition; + jitterFilter = src.jitterFilter; + beepANACenter = src.beepANACenter; + extendedLimits = src.extendedLimits; + extendedTrims = src.extendedTrims; + throttleReversed = src.throttleReversed; + checklistInteractive = src.checklistInteractive; + memcpy(&flightModeData[0], &src.flightModeData[0], sizeof(flightModeData[0]) * CPN_MAX_FLIGHT_MODES); + memcpy(&mixData[0], &src.mixData[0], sizeof(mixData[0]) * CPN_MAX_MIXERS); + memcpy(&limitData[0], &src.limitData[0], sizeof(limitData[0]) * CPN_MAX_CHNOUT); + memcpy(&inputNames, &src.inputNames, sizeof(inputNames)); + memcpy(&expoData[0], &src.expoData[0], sizeof(expoData[0]) * CPN_MAX_EXPOS); + memcpy(&curves[0], &src.curves[0], sizeof(curves[0]) * CPN_MAX_CURVES); + memcpy(&logicalSw[0], &src.logicalSw[0], sizeof(logicalSw[0]) * CPN_MAX_LOGICAL_SWITCHES); + memcpy(&customFn[0], &src.customFn[0], sizeof(customFn[0]) * CPN_MAX_SPECIAL_FUNCTIONS); + swashRingData = src.swashRingData; + thrTraceSrc = src.thrTraceSrc; + switchWarningStates = src.switchWarningStates; + thrTrimSwitch = src.thrTrimSwitch; + potsWarningMode = src.potsWarningMode; + memcpy(&potsWarnEnabled[0], &src.potsWarnEnabled[0], sizeof(potsWarnEnabled[0]) * CPN_MAX_INPUTS); + memcpy(&potsWarnPosition[0], &src.potsWarnPosition[0], sizeof(potsWarnPosition[0]) * CPN_MAX_INPUTS); + displayChecklist = src.displayChecklist; + memcpy(&gvarData[0], &src.gvarData[0], sizeof(gvarData[0]) * CPN_MAX_GVARS); + mavlink = src.mavlink; + telemetryProtocol = src.telemetryProtocol; + frsky = src.frsky; + rssiSource = src.rssiSource; + rssiAlarms = src.rssiAlarms; + showInstanceIds = src.showInstanceIds; + memcpy(&bitmap, &src.bitmap, sizeof(bitmap)); + trainerMode = src.trainerMode; + memcpy(&moduleData[0], &src.moduleData[0], sizeof(moduleData[0]) * (CPN_MAX_MODULES + 1)); + memcpy(&scriptData[0], &src.scriptData[0], sizeof(scriptData[0]) * CPN_MAX_SCRIPTS); + memcpy(&sensorData[0], &src.sensorData[0], sizeof(sensorData[0]) * CPN_MAX_SENSORS); + toplcdTimer = src.toplcdTimer; + customScreens = src.customScreens; + topBarData = src.topBarData; + memcpy(&topbarWidgetWidth[0], &src.topbarWidgetWidth[0], sizeof(topbarWidgetWidth[0]) * MAX_TOPBAR_ZONES); + view = src.view; + memcpy(®istrationId, &src.registrationId, sizeof(registrationId)); + hatsMode = src.hatsMode; + radioThemesDisabled = src.radioThemesDisabled; + radioGFDisabled = src.radioGFDisabled; + radioTrainerDisabled = src.radioTrainerDisabled; + modelHeliDisabled = src.modelHeliDisabled; + modelFMDisabled = src.modelFMDisabled; + modelCurvesDisabled = src.modelCurvesDisabled; + modelGVDisabled = src.modelGVDisabled; + modelLSDisabled = src.modelLSDisabled; + modelSFDisabled = src.modelSFDisabled; + modelCustomScriptsDisabled = src.modelCustomScriptsDisabled; + modelTelemetryDisabled = src.modelTelemetryDisabled; + memcpy(&customSwitches[0], &src.customSwitches[0], sizeof(customSwitches[0]) * CPN_MAX_SWITCHES_FUNCTION); + memcpy(&cfsGroupOn[0], &src.cfsGroupOn[0], sizeof(cfsGroupOn[0]) * CPN_MAX_CUSTOMSWITCH_GROUPS); + usbJoystickExtMode = src.usbJoystickExtMode; + usbJoystickIfMode = src.usbJoystickIfMode; + usbJoystickCircularCut = src.usbJoystickCircularCut; + memcpy(&usbJoystickCh[0], &src.usbJoystickCh[0], sizeof(usbJoystickCh[0]) * CPN_USBJ_MAX_JOYSTICK_CHANNELS); + checklistData = src.checklistData; + updRefList = nullptr; + memset(&updRefInfo, 0, sizeof(updRefInfo)); +} + ExpoData * ModelData::insertInput(const int idx) { memmove(&expoData[idx + 1], &expoData[idx], (CPN_MAX_EXPOS - (idx + 1)) * sizeof(ExpoData)); @@ -145,48 +226,130 @@ void ModelData::clearMixes() void ModelData::clear() { - memset(reinterpret_cast(this), 0, sizeof(ModelData)); + // IMPORTANT: DO NOT USE + // memset(reinterpret_cast(this), 0, sizeof(ModelData)); + // as struct contains complex data types eg std::string + + memset(&semver, 0, sizeof(semver)); + used = false; + memset(&name, 0, sizeof(name)); + memset(&filename, 0, sizeof(filename)); + memset(&labels, 0, sizeof(labels)); modelIndex = -1; // an invalid index, this is managed by the TreeView data model - moduleData[0].protocol = PULSES_OFF; - moduleData[1].protocol = PULSES_OFF; - moduleData[0].channelsCount = 8; - moduleData[1].channelsStart = 0; - moduleData[1].channelsCount = 8; - moduleData[0].ppm.delay = 300; - moduleData[1].ppm.delay = 300; - moduleData[2].ppm.delay = 300; //Trainer PPM - for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { + modelUpdated = false; + modelErrors = false; + noGlobalFunctions = false; + thrTrim = false; + trimInc = 0; + trimsDisplay = 0; + disableThrottleWarning = false; + enableCustomThrottleWarning = false; + customThrottleWarningPosition = 0; + jitterFilter = 0; + beepANACenter = 0; + extendedLimits = false; + extendedTrims = false; + throttleReversed = false; + checklistInteractive = false; + memset(&inputNames, 0, sizeof(inputNames)); + thrTraceSrc = 0; + switchWarningStates = 0; + thrTrimSwitch = 0; + potsWarningMode = 0; + mavlink.clear(); + telemetryProtocol = 0; + frsky.clear(); + rssiSource = 0; + rssiAlarms.clear(); + showInstanceIds = false; + memset(&bitmap, 0, sizeof(bitmap)); + trainerMode = TRAINER_MODE_OFF; + + for (int i = 0; i < CPN_MAX_INPUTS; i++) + potsWarnEnabled[i] = false; + + for (int i = 0; i < CPN_MAX_INPUTS; i++) + potsWarnPosition[i] = 0; + + displayChecklist = false; + + for (int i = 0; i < CPN_MAX_MODULES + 1/*Trainer*/; i++) // + 1 + moduleData[i].clear(); + + for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) flightModeData[i].clear(i); - } - for (int i = 0; i < CPN_MAX_GVARS; i++) { + + for (int i = 0; i < CPN_MAX_GVARS; i++) gvarData[i].clear(); - } + clearInputs(); clearMixes(); + for (int i = 0; i < CPN_MAX_CHNOUT; i++) limitData[i].clear(); - for (int i = 0; i < CPN_MAX_STICKS; i++) - expoData[i].clear(); + for (int i = 0; i < CPN_MAX_LOGICAL_SWITCHES; i++) logicalSw[i].clear(); + for (int i = 0; i < CPN_MAX_SPECIAL_FUNCTIONS; i++) customFn[i].clear(); + for (int i = 0; i < CPN_MAX_CURVES; i++) curves[i].clear(); + for (int i = 0; i < CPN_MAX_TIMERS; i++) timers[i].clear(); + swashRingData.clear(); frsky.clear(); rssiAlarms.clear(); + for (unsigned i = 0; i < CPN_MAX_SENSORS; i++) sensorData[i].clear(); - trainerMode = TRAINER_MODE_OFF; + toplcdTimer = 0; + RadioLayout::init("Layout2P1", customScreens); + topBarData.clear(); - const char * layoutId = "Layout2P1"; // currently all using same default though might change for NV14 - RadioLayout::init(layoutId, customScreens); + for (int i = 0; i < MAX_TOPBAR_ZONES; i++) + topbarWidgetWidth[i] = 0; + view = 0; + memset(®istrationId, 0, sizeof(registrationId)); hatsMode = GeneralSettings::HATSMODE_GLOBAL; + + radioThemesDisabled = 0; + radioGFDisabled = 0; + radioTrainerDisabled = 0; + modelHeliDisabled = 0; + modelFMDisabled = 0; + modelCurvesDisabled = 0; + modelGVDisabled = 0; + modelLSDisabled = 0; + modelSFDisabled = 0; + modelCustomScriptsDisabled = 0; + modelTelemetryDisabled = 0; + + for (int i = 0; i < CPN_MAX_SWITCHES_FUNCTION; i++) + customSwitches[i].clear(); + + for (int i = 0; i < CPN_MAX_CUSTOMSWITCH_GROUPS; i++) + cfsGroupOn[i] = 0; + + usbJoystickExtMode = 0; + usbJoystickIfMode = 0; + usbJoystickCircularCut = 0; + + for (int i = 0; i < CPN_USBJ_MAX_JOYSTICK_CHANNELS; i++) + usbJoystickCh[i].clear(); + + checklistData.clear(); + + if (updRefList) + delete updRefList; + + updRefList = nullptr; + memset(&updRefInfo, 0, sizeof(updRefInfo)); } bool ModelData::isEmpty() const @@ -242,6 +405,7 @@ void ModelData::setDefaultFunctionSwitches(int functionSwitchCount) customSwitches[i].onColor.setColor(255, 255, 255); customSwitches[i].offColor.setColor(0, 0, 0); } + cfsGroupOn[1] = 1; } @@ -249,7 +413,7 @@ void ModelData::setDefaultValues(unsigned int id, const GeneralSettings & settin { clear(); used = true; - sprintf(name, "MODEL%02d", id+1); + sprintf(name, "MODEL%02d", id + 1); for (int i = 0; i < CPN_MAX_MODULES; i++) { moduleData[i].modelId = id + 1; } diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 3cd71cfc26d..4dd91fe1b19 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -105,9 +105,11 @@ class USBJoystickChData { void clear() { memset(reinterpret_cast(this), 0, sizeof(USBJoystickChData)); } }; -class customSwitch { +#define CPN_MAX_CUSTOMSWITCH_GROUPS 4 + +class CustomSwitchData { public: - customSwitch() { clear(); } + CustomSwitchData() { clear(); } Board::SwitchType type; unsigned int group; unsigned int start; @@ -117,7 +119,7 @@ class customSwitch { unsigned int offColorLuaOverride; RGBLedColor onColor; RGBLedColor offColor; - void clear() { memset(reinterpret_cast(this), 0, sizeof(customSwitch)); } + void clear() { memset(reinterpret_cast(this), 0, sizeof(CustomSwitchData)); } }; class ModelData { @@ -181,7 +183,7 @@ class ModelData { char bitmap[CPN_MAX_BITMAP_LEN + 1]; - unsigned int trainerMode; // TrainerMode + unsigned int trainerMode; ModuleData moduleData[CPN_MAX_MODULES + 1/*trainer*/]; @@ -222,8 +224,8 @@ class ModelData { }; // Function switches - customSwitch customSwitches[CPN_MAX_SWITCHES_FUNCTION]; - unsigned int cfsGroupOn[4]; + CustomSwitchData customSwitches[CPN_MAX_SWITCHES_FUNCTION]; + unsigned int cfsGroupOn[CPN_MAX_CUSTOMSWITCH_GROUPS]; // Custom USB joytsick mapping unsigned int usbJoystickExtMode; @@ -233,7 +235,7 @@ class ModelData { QByteArray checklistData; - ModelData & operator = (const ModelData & src); + ModelData & operator=(const ModelData & src); void convert(RadioDataConversionState & cstate); @@ -248,6 +250,7 @@ class ModelData { QVector mixes(int channel) const; void clear(); + void copy(const ModelData & src); bool isEmpty() const; void setDefaultInputs(const GeneralSettings & settings); void setDefaultMixes(const GeneralSettings & settings); diff --git a/companion/src/firmwares/moduledata.cpp b/companion/src/firmwares/moduledata.cpp index 10dd31024fd..78a5e103cb8 100644 --- a/companion/src/firmwares/moduledata.cpp +++ b/companion/src/firmwares/moduledata.cpp @@ -65,6 +65,14 @@ void ModuleData::convert(RadioDataConversionState & cstate) } } +void ModuleData::clear() +{ + memset(reinterpret_cast(this), 0, sizeof(ModuleData)); + protocol = PULSES_OFF; + channelsCount = 8; + ppm.delay = 300; +} + // moved from OpenTxFirmware EdgeTX v2.9 // only called by ModuleData::convert // TODO: merge with ModuleData::isProtocolAvailable as share much of the same logic diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index ec81dd619d8..afd95b07ad0 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -215,7 +215,7 @@ class ModuleData { unsigned int flags; } dsmp; - void clear() { memset(reinterpret_cast(this), 0, sizeof(ModuleData)); } + void clear(); void convert(RadioDataConversionState & cstate); bool isPxx2Module() const; bool supportRxNum() const;