diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 1febe265800..18c39d1286a 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -63,6 +63,7 @@ else() option(USBJ_EX "Enable USB Joystick Extension" ON) endif() option(POWER_LED_BLUE "Override Power LED to be normally Blue" OFF) +option(VCONTROLS "Enable virtual controls support" ON) # since we reset all default CMAKE compiler flags for firmware builds, provide an alternate way for user to specify additional flags. set(FIRMWARE_C_FLAGS "" CACHE STRING "Additional flags for firmware target c compiler (note: all CMAKE_C_FLAGS[_*] are ignored for firmware/bootloader).") @@ -389,6 +390,10 @@ if(DISABLE_MCUCHECK) add_definitions(-DDISABLE_MCUCHECK) endif() +if(VCONTROLS) + add_definitions(-DVCONTROLS) +endif() + set(SRC ${SRC} edgetx.cpp @@ -427,6 +432,9 @@ if(GUI) endforeach() endif() +if(VCONTROLS) + set(SRC ${SRC} vcontrols.cpp) +endif() if(USBJ_EX) add_definitions(-DUSBJ_EX) diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 5ed0e87d242..fcabe7d3afa 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -55,6 +55,8 @@ #define MAX_TRAINER_CHANNELS 16 #define MAX_TELEMETRY_SENSORS 60 #define MAX_CUSTOM_SCREENS 10 + #define MAX_VIRTUAL_INPUTS 16 + #define MAX_VIRTUAL_SWITCHES 64 #elif defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) #define MAX_MODELS 60 #define MAX_OUTPUT_CHANNELS 32 // number of real output channels CH1-CH32 @@ -441,6 +443,11 @@ enum SwitchSources { SWSRC_FIRST_LOGICAL_SWITCH SKIP, SWSRC_LAST_LOGICAL_SWITCH SKIP = SWSRC_FIRST_LOGICAL_SWITCH + MAX_LOGICAL_SWITCHES - 1, +#if defined(VCONTROLS) && defined(COLORLCD) + SWSRC_FIRST_VIRTUAL_SWITCH SKIP, + SWSRC_LAST_VIRTUAL_SWITCH SKIP = SWSRC_FIRST_VIRTUAL_SWITCH + MAX_VIRTUAL_SWITCHES - 1, +#endif + SWSRC_ON, SWSRC_ONE, @@ -483,6 +490,7 @@ enum SwitchTypes { SW_FLIGHT_MODE = 1 << 3, SW_TELEM = 1 << 4, SW_OTHER = 1 << 5, + SW_VIRTUAL = 1 << 6, SW_NONE = 1 << 20, }; @@ -547,6 +555,11 @@ enum MixSources { MIXSRC_FIRST_CH SKIP, MIXSRC_LAST_CH SKIP = MIXSRC_FIRST_CH + MAX_OUTPUT_CHANNELS - 1, +#if defined(VCONTROLS) && defined(COLORLCD) + MIXSRC_FIRST_VCONTROL SKIP, + MIXSRC_LAST_VCONTROL SKIP = MIXSRC_FIRST_VCONTROL + MAX_VIRTUAL_INPUTS - 1, +#endif + MIXSRC_FIRST_GVAR SKIP, MIXSRC_LAST_GVAR SKIP = MIXSRC_FIRST_GVAR + MAX_GVARS - 1, @@ -596,6 +609,7 @@ enum SrcTypes { SRC_TELEM_COMP = 1 << 19, SRC_NONE = 1 << 20, SRC_INVERT = 1 << 21, + SRC_VCONTROL = 1 << 22, }; enum BacklightMode { diff --git a/radio/src/gui/colorlcd/controls/sourcechoice.cpp b/radio/src/gui/colorlcd/controls/sourcechoice.cpp index 6e82e452546..cb4f4644826 100644 --- a/radio/src/gui/colorlcd/controls/sourcechoice.cpp +++ b/radio/src/gui/colorlcd/controls/sourcechoice.cpp @@ -87,6 +87,10 @@ class SourceChoiceMenuToolbar : public MenuToolbar nullptr, STR_MENU_TRAINER); addButton(STR_CHAR_CHANNEL, MIXSRC_FIRST_CH, MIXSRC_LAST_CH, nullptr, STR_MENU_CHANNELS); +#if defined(VCONTROLS) && defined(COLORLCD) + addButton("VI", MIXSRC_FIRST_VCONTROL, MIXSRC_LAST_VCONTROL, nullptr, + STR_MENU_VCONTROL); +#endif #if defined(GVARS) if (modelGVEnabled()) addButton(STR_CHAR_SLIDER, MIXSRC_FIRST_GVAR, MIXSRC_LAST_GVAR, nullptr, diff --git a/radio/src/gui/colorlcd/controls/switchchoice.cpp b/radio/src/gui/colorlcd/controls/switchchoice.cpp index 33372fd03ae..d90c3387003 100644 --- a/radio/src/gui/colorlcd/controls/switchchoice.cpp +++ b/radio/src/gui/colorlcd/controls/switchchoice.cpp @@ -39,6 +39,8 @@ class SwitchChoiceMenuToolbar : public MenuToolbar STR_MENU_TRIMS); addButton("LS", SWSRC_FIRST_LOGICAL_SWITCH, SWSRC_LAST_LOGICAL_SWITCH, nullptr, STR_MENU_LOGICAL_SWITCHES); + addButton("VS", SWSRC_FIRST_VIRTUAL_SWITCH, SWSRC_LAST_VIRTUAL_SWITCH, + nullptr, STR_MENU_VIRTUAL_SWITCHES); addButton("FM", SWSRC_FIRST_FLIGHT_MODE, SWSRC_LAST_FLIGHT_MODE, nullptr, STR_FLIGHT_MODE); addButton(STR_CHAR_TELEMETRY, SWSRC_FIRST_SENSOR, SWSRC_LAST_SENSOR, diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index 25fbcf80d11..145a01f08e1 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -28,6 +28,10 @@ #include "switches.h" #include "mixes.h" +#if defined(VCONTROLS) && defined(COLORLCD) +#include "vcontrols.h" +#endif + #undef CPN #include "MultiSubtypeDefs.h" @@ -222,7 +226,15 @@ static bool isSourceLSAvailable(int source) { static bool isSourceTrainerAvailable(int source) { return g_model.trainerData.mode > 0; } - +#if defined(VCONTROLS) && defined(COLORLCD) +static bool isSourceVControlAvailable(int source) { + if (source >= 0) { + const uint32_t mask = (1UL << source); + return (activeVirtualInputs & mask); + } + return false; +} +#endif static bool isSourceGvarAvailable(int source) { #if defined(GVARS) return modelGVEnabled(); @@ -282,6 +294,9 @@ static struct sourceAvailableCheck sourceChecks[] = { { MIXSRC_FIRST_TRAINER, MIXSRC_LAST_TRAINER, SRC_TRAINER, isSourceTrainerAvailable }, { MIXSRC_FIRST_CH, MIXSRC_LAST_CH, SRC_CHANNEL, isChannelUsed }, { MIXSRC_FIRST_CH, MIXSRC_LAST_CH, SRC_CHANNEL_ALL, sourceIsAvailable }, +#if defined(VCONTROLS) && defined(COLORLCD) + { MIXSRC_FIRST_VCONTROL, MIXSRC_LAST_VCONTROL, SRC_VCONTROL, isSourceVControlAvailable }, +#endif { MIXSRC_FIRST_GVAR, MIXSRC_LAST_GVAR, SRC_GVAR, isSourceGvarAvailable }, { MIXSRC_TX_VOLTAGE, MIXSRC_TX_GPS, SRC_TX, sourceIsAvailable }, { MIXSRC_FIRST_TIMER, MIXSRC_LAST_TIMER, SRC_TIMER, isSourceTimerAvailable }, @@ -306,7 +321,7 @@ bool checkSourceAvailable(int source, uint32_t sourceTypes) #define SRC_COMMON \ SRC_STICK | SRC_POT | SRC_TILT | SRC_SPACEMOUSE | SRC_MINMAX | SRC_TRIM | \ - SRC_SWITCH | SRC_FUNC_SWITCH | SRC_LOGICAL_SWITCH | SRC_TRAINER | SRC_GVAR + SRC_SWITCH | SRC_FUNC_SWITCH | SRC_LOGICAL_SWITCH | SRC_TRAINER | SRC_GVAR | SRC_VCONTROL bool isSourceAvailable(int source) { @@ -391,7 +406,14 @@ bool isSwitchAvailable(int swtch, SwitchContext context) int index = (swtch - SWSRC_FIRST_TRIM) / 2; return index < keysGetMaxTrims(); } - + +#if defined(VCONTROLS) && defined(COLORLCD) + if ((swtch >= SWSRC_FIRST_VIRTUAL_SWITCH) && (swtch <= SWSRC_LAST_VIRTUAL_SWITCH)) { + const uint64_t mask = (uint64_t{1} << (swtch - SWSRC_FIRST_VIRTUAL_SWITCH)); + return (activeVirtualSwitches & mask); + } +#endif + if (swtch >= SWSRC_FIRST_LOGICAL_SWITCH && swtch <= SWSRC_LAST_LOGICAL_SWITCH) { if (context == GeneralCustomFunctionsContext) { return false; @@ -481,6 +503,13 @@ static bool isSwitchTelemAvailable(int swtch, bool invert) { return isTelemetryFieldAvailable(swtch); } +#if defined(VCONTROLS) && defined(COLORLCD) +static bool isVSwitchAvailable(int swtch, bool invert) { + const uint64_t mask = (uint64_t{1} << swtch); + return (activeVirtualSwitches & mask); +} +#endif + static bool isSwitchOtherAvailable(int swtch, bool invert) { swtch += SWSRC_ON; if (invert && (swtch == SWSRC_ON || swtch == SWSRC_ONE)) @@ -506,6 +535,9 @@ static struct switchAvailableCheck switchChecks[] = { { SWSRC_FIRST_SWITCH, SWSRC_LAST_MULTIPOS_SWITCH, SW_SWITCH, isSwitchSwitchAvailable }, { SWSRC_FIRST_TRIM, SWSRC_LAST_TRIM, SW_TRIM, isSwitchTrimAvailable }, { SWSRC_FIRST_LOGICAL_SWITCH, SWSRC_LAST_LOGICAL_SWITCH, SW_LOGICAL_SWITCH, isSwitchLSAvailable }, +#if defined(VCONTROLS) && defined(COLORLCD) + { SWSRC_FIRST_VIRTUAL_SWITCH, SWSRC_LAST_VIRTUAL_SWITCH, SW_VIRTUAL, isVSwitchAvailable }, +#endif { SWSRC_FIRST_FLIGHT_MODE, SWSRC_LAST_FLIGHT_MODE, SW_FLIGHT_MODE, isSwitchFMAvailable }, { SWSRC_FIRST_SENSOR, SWSRC_LAST_SENSOR, SW_TELEM, isSwitchTelemAvailable }, { SWSRC_ON, SWSRC_COUNT - 1, SW_OTHER, isSwitchOtherAvailable }, diff --git a/radio/src/lua/api_colorlcd_lvgl.cpp b/radio/src/lua/api_colorlcd_lvgl.cpp index 5e910cd0062..3dc5772e940 100644 --- a/radio/src/lua/api_colorlcd_lvgl.cpp +++ b/radio/src/lua/api_colorlcd_lvgl.cpp @@ -393,6 +393,9 @@ LROT_BEGIN(lvgllib, NULL, 0) LROT_NUMENTRY(SW_SWITCH, SW_SWITCH) LROT_NUMENTRY(SW_TRIM, SW_TRIM) LROT_NUMENTRY(SW_LOGICAL_SWITCH, SW_LOGICAL_SWITCH) +#if defined(VCONTROLS) && defined(COLORLCD) + LROT_NUMENTRY(SW_VIRTUAL, SW_VIRTUAL) +#endif LROT_NUMENTRY(SW_TELEM, SW_TELEM) LROT_NUMENTRY(SW_OTHER, SW_OTHER) LROT_NUMENTRY(SW_CLEAR, SW_NONE) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 161801362a6..3fe71b70d1b 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -63,6 +63,11 @@ #define RADIO_VERSION FLAVOUR #endif +#if defined(VCONTROLS) && defined(COLORLCD) +#include +#include "vcontrols.h" +#endif + #define VERSION_OSNAME "EdgeTX" #define FIND_FIELD_DESC 0x01 @@ -2466,6 +2471,89 @@ static int luaSerialSetPower(lua_State* L) } #endif +#if defined(VCONTROLS) && defined(COLORLCD) +static int luaActivateVirtualSwitch(lua_State * L) { + const int sw = luaL_checkinteger(L, 1); + const bool on = lua_toboolean(L, 2); + + if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { + if (on) { + activeVirtualSwitches |= (uint64_t{1} << (sw - 1)); + } + else { + activeVirtualSwitches &= ~(uint64_t{1} << (sw - 1)); + } + } + return 0; +} +static int luaActivateVirtualInput(lua_State * L) { + const int ch = luaL_checkinteger(L, 1); + const bool on = lua_toboolean(L, 2); + + if (1 <= ch && ch <= MAX_VIRTUAL_INPUTS) { + if (on) { + activeVirtualInputs |= (1 << (ch - 1)); + } + else { + activeVirtualInputs &= ~(1 << (ch - 1)); + } + } + return 0; +} +static int luaGetVirtualSwitch(lua_State * L) +{ + const int sw = luaL_checkinteger(L, 1); + + if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { + const bool v = virtualSwitches & (uint64_t{1} << (sw - 1)); + lua_pushboolean(L, v); + } + else { + lua_pushnil(L); + } + return 1; +} + +static int luaSetVirtualSwitch(lua_State * L) +{ + const int sw = luaL_checkinteger(L, 1); + const bool on = lua_toboolean(L, 2); + + if (1 <= sw && sw <= MAX_VIRTUAL_SWITCHES) { + if (on) { + virtualSwitches |= (uint64_t{1} << (sw - 1)); + } + else { + virtualSwitches &= ~(uint64_t{1} << (sw - 1)); + } + } + return 0; +} +static int luaSetVirtualInput(lua_State * L) +{ + int ch = luaL_checkinteger(L, 1); + int value = std::clamp(luaL_checkinteger(L, 2), -1024, 1024); + + if (1 <= ch && ch <= MAX_VIRTUAL_INPUTS) { + virtualInputs[ch - 1] = value; + } + return 0; +} +static int luaGetVirtualInput(lua_State * L) +{ + const int ch = luaL_checkinteger(L, 1); + + if (1 <= ch && ch <= MAX_VIRTUAL_INPUTS) { + const int value = virtualInputs[ch - 1]; + lua_pushinteger(L, value); + } + else { + lua_pushnil(L); + } + return 1; +} +#endif + #if defined(COLORLCD) static int shmVar[16] = {0}; @@ -2998,6 +3086,14 @@ LROT_BEGIN(etxlib, NULL, 0) #if defined(COLORLCD) LROT_FUNCENTRY( setShmVar, luaSetShmVar ) LROT_FUNCENTRY( getShmVar, luaGetShmVar ) +#endif +#if defined(VCONTROLS) && defined(COLORLCD) + LROT_FUNCENTRY( setVirtualInput, luaSetVirtualInput) + LROT_FUNCENTRY( getVirtualInput, luaGetVirtualInput) + LROT_FUNCENTRY( setVirtualSwitch, luaSetVirtualSwitch) + LROT_FUNCENTRY( getVirtualSwitch, luaGetVirtualSwitch) + LROT_FUNCENTRY( activateVirtualSwitch, luaActivateVirtualSwitch) + LROT_FUNCENTRY( activateVirtualInput, luaActivateVirtualInput) #endif LROT_FUNCENTRY( setStickySwitch, luaSetStickySwitch ) LROT_FUNCENTRY( getLogicalSwitchValue, luaGetLogicalSwitchValue ) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 730eb7b4521..5eb9c18134a 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -25,6 +25,7 @@ #include "switches.h" #include "input_mapping.h" #include "mixes.h" +#include "vcontrols.h" #include "hal/adc_driver.h" #include "hal/trainer_driver.h" @@ -480,7 +481,11 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) } else if (i <= MIXSRC_LAST_CH) { return ex_chans[i - MIXSRC_FIRST_CH]; } - +#if defined(VCONTROLS) && defined(COLORLCD) + else if (i <= MIXSRC_LAST_VCONTROL) { + return virtualInputs[i - MIXSRC_FIRST_VCONTROL]; + } +#endif else if (i <= MIXSRC_LAST_GVAR) { #if defined(GVARS) return GVAR_VALUE(i - MIXSRC_FIRST_GVAR, getGVarFlightMode(mixerCurrentFlightMode, i - MIXSRC_FIRST_GVAR)); @@ -489,7 +494,6 @@ getvalue_t _getValue(mixsrc_t i, bool* valid) return 0; #endif } - else if (i == MIXSRC_TX_VOLTAGE) { return g_vbat100mV; } else if (i < MIXSRC_FIRST_TIMER) { diff --git a/radio/src/storage/storage_common.cpp b/radio/src/storage/storage_common.cpp index 2fec387a5cd..a0017e8727d 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -25,6 +25,10 @@ #include "mixes.h" #include "switches.h" +#if defined(VCONTROLS) && defined(COLORLCD) +#include "vcontrols.h" +#endif + #if defined(COLORLCD) #include "view_main.h" #endif @@ -253,6 +257,10 @@ if(g_model.rssiSource) { logicalSwitchesInit(false); +#if defined(VCONTROLS) && defined(COLORLCD) + resetVirtualControls(); +#endif + restoreTimers(); for (int i=0; i 4 && + val[0] == 'v' && + val[1] == 'i' && + val[2] == 'n' && + val[3] == '(') { + + val += 4; val_len -= 4; + // parse int and ignore closing ')' + return yaml_str2uint(val, val_len) + MIXSRC_FIRST_VCONTROL; +#endif } else if (val_len > 3 && val[0] == 'g' && val[1] == 'v' && @@ -392,6 +404,16 @@ static bool w_mixSrcRaw(const YamlNode* node, uint32_t val, yaml_writer_func wf, return false; str = closing_parenthesis; } +#if defined(VCONTROLS) && defined(COLORLCD) + else if (val >= MIXSRC_FIRST_VCONTROL + && val <= MIXSRC_LAST_VCONTROL) { + + val -= MIXSRC_FIRST_VCONTROL; + if (!output_source_1_param("vin(", 4, val, wf, opaque)) + return false; + str = closing_parenthesis; + } +#endif else if (val >= MIXSRC_FIRST_GVAR && val <= MIXSRC_LAST_GVAR) { @@ -1067,6 +1089,14 @@ static uint32_t r_swtchSrc(const YamlNode* node, const char* val, uint8_t val_le ival = SWSRC_FIRST_LOGICAL_SWITCH + yaml_str2int(val+1, val_len-1) - 1; } +#if defined(VCONTROLS) && defined(COLORLCD) + else if (val_len >= 2 + && val[0] == 'V' + && (val[1] >= '0' && val[1] <= '9')) { + + ival = SWSRC_FIRST_VIRTUAL_SWITCH + yaml_str2int(val+1, val_len-1) - 1; + } +#endif else if (val_len == 3 && val[0] == 'F' && val[1] == 'M' @@ -1133,7 +1163,15 @@ static bool w_swtchSrc_unquoted(const YamlNode* node, uint32_t val, wf(opaque, "L", 1); str = yaml_unsigned2str(sval - SWSRC_FIRST_LOGICAL_SWITCH + 1); return wf(opaque,str, strlen(str)); + } +#if defined(VCONTROLS) && defined(COLORLCD) + else if (sval <= SWSRC_LAST_VIRTUAL_SWITCH) { + + wf(opaque, "V", 1); + str = yaml_unsigned2str(sval - SWSRC_FIRST_VIRTUAL_SWITCH + 1); + return wf(opaque,str, strlen(str)); } +#endif else if (sval <= SWSRC_LAST_FLIGHT_MODE) { wf(opaque, "FM", 2); diff --git a/radio/src/strhelpers.cpp b/radio/src/strhelpers.cpp index dfb3243f184..e82780d82b8 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -496,6 +496,11 @@ char *getSwitchPositionName(char *dest, swsrc_t idx) } else if (idx <= SWSRC_LAST_LOGICAL_SWITCH) { *s++ = 'L'; strAppendUnsigned(s, idx - SWSRC_FIRST_LOGICAL_SWITCH + 1, 2); +#if defined(VCONTROLS) && defined(COLORLCD) + } else if (idx <= SWSRC_LAST_VIRTUAL_SWITCH) { + *s++ = 'V'; + strAppendUnsigned(s, idx - SWSRC_FIRST_VIRTUAL_SWITCH + 1, 2); +#endif } else if (idx <= SWSRC_ONE) { idx -= SWSRC_ON; getStringAtIndex(s, STR_ON_ONE_SWITCHES, idx); @@ -732,7 +737,13 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx) } else { strAppendStringWithIndex(dest, STR_CH, ch + 1); } - } else if (idx <= MIXSRC_LAST_GVAR) { + } +#if defined(VCONTROLS) && defined(COLORLCD) + else if (idx <= MIXSRC_LAST_VCONTROL) { + strAppendStringWithIndex(dest, STR_VC, idx + 1 - MIXSRC_FIRST_VCONTROL); + } +#endif + else if (idx <= MIXSRC_LAST_GVAR) { idx -= MIXSRC_FIRST_GVAR; #if defined(LIBOPENUI) char *s = strAppendStringWithIndex(dest, STR_GV, idx + 1); diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index d3c687f7620..fbc6c52780b 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -30,6 +30,9 @@ #include "input_mapping.h" #include "inactivity_timer.h" #include "tasks/mixer_task.h" +#if defined(VCONTROLS) +#include "vcontrols.h" +#endif #define CS_LAST_VALUE_INIT -32768 @@ -770,6 +773,13 @@ bool getSwitch(swsrc_t swtch, uint8_t flags) result = false; #endif } +#if defined(VCONTROLS) && defined(COLORLCD) + else if ((cs_idx >= SWSRC_FIRST_VIRTUAL_SWITCH) && (cs_idx <= SWSRC_LAST_VIRTUAL_SWITCH)) { + cs_idx -= SWSRC_FIRST_VIRTUAL_SWITCH; + const uint64_t mask = (uint64_t{1} << cs_idx); + result = virtualSwitches & mask; + } +#endif else { cs_idx -= SWSRC_FIRST_LOGICAL_SWITCH; result = lswFm[mixerCurrentFlightMode].lsw[cs_idx].state; diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index b3ec71b956c..96e98a4fb42 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -241,6 +241,7 @@ const char STR_SLOWDOWN[] = TR_SLOWDOWN; const char STR_SLOWUP[] = TR_SLOWUP; const char STR_MIXES[] = TR_MIXES; const char STR_CV[] = TR_CV; +const char STR_VC[] = TR_VC; const char STR_GV[] = TR_GV; const char STR_RANGE[] = TR_RANGE; const char STR_CENTER[] = TR_CENTER; @@ -744,8 +745,10 @@ const char STR_MENU_HELI[] = TR_MENU_HELI; const char STR_MENU_TRIMS[] = TR_MENU_TRIMS; const char STR_MENU_SWITCHES[] = TR_MENU_SWITCHES; const char STR_MENU_LOGICAL_SWITCHES[] = TR_MENU_LOGICAL_SWITCHES; +const char STR_MENU_VIRTUAL_SWITCHES[] = TR_MENU_VIRTUAL_SWITCHES; const char STR_MENU_TRAINER[] = TR_MENU_TRAINER; const char STR_MENU_CHANNELS[] = TR_MENU_CHANNELS; +const char STR_MENU_VCONTROL[] = TR_MENU_VCONTROL; const char STR_MENU_GVARS[] = TR_MENU_GVARS; const char STR_MENU_TELEMETRY[] = TR_MENU_TELEMETRY; const char STR_MENU_DISPLAY[] = TR_MENU_DISPLAY; diff --git a/radio/src/translations.h b/radio/src/translations.h index d126c949560..8b90b66665a 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -373,6 +373,7 @@ extern const char STR_SLOWDOWN[]; extern const char STR_SLOWUP[]; extern const char STR_MIXES[]; extern const char STR_CV[]; +extern const char STR_VC[]; extern const char STR_GV[]; extern const char STR_RANGE[]; extern const char STR_CENTER[]; @@ -1132,8 +1133,10 @@ extern const char STR_MENU_HELI[]; extern const char STR_MENU_TRIMS[]; extern const char STR_MENU_SWITCHES[]; extern const char STR_MENU_LOGICAL_SWITCHES[]; +extern const char STR_MENU_VIRTUAL_SWITCHES[]; extern const char STR_MENU_TRAINER[]; extern const char STR_MENU_CHANNELS[]; +extern const char STR_MENU_VCONTROL[]; extern const char STR_MENU_GVARS[]; extern const char STR_MENU_TELEMETRY[]; extern const char STR_MENU_DISPLAY[]; diff --git a/radio/src/translations/de.h b/radio/src/translations/de.h index 98dd68ee59e..f18c4570bcf 100644 --- a/radio/src/translations/de.h +++ b/radio/src/translations/de.h @@ -346,6 +346,7 @@ #define TR_SLOWUP "Langs.Up" #define TR_MIXES "MISCHER" #define TR_CV "KV" +#define TR_VC "VIn" #if defined(PCBNV14) || defined(PCBPL18) #define TR_GV "GV" #else @@ -1174,8 +1175,10 @@ #define TR_MENU_TRIMS STR_CHAR_TRIM "Trimmung" #define TR_MENU_SWITCHES STR_CHAR_SWITCH "Schalter" #define TR_MENU_LOGICAL_SWITCHES STR_CHAR_SWITCH "Log. Schalter" +#define TR_MENU_VIRTUAL_SWITCHES STR_CHAR_SWITCH "Virt. Schalter" #define TR_MENU_TRAINER STR_CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS STR_CHAR_CHANNEL "Kanäle" +#define TR_MENU_VCONTROL "Virtuals" #define TR_MENU_GVARS STR_CHAR_SLIDER "Glob. Vars" #define TR_MENU_TELEMETRY STR_CHAR_TELEMETRY "Telemetrie" #define TR_MENU_DISPLAY "TELM-SEITEN" diff --git a/radio/src/translations/en.h b/radio/src/translations/en.h index 6125d4e6ff6..cd6b172d735 100644 --- a/radio/src/translations/en.h +++ b/radio/src/translations/en.h @@ -345,6 +345,7 @@ #define TR_SLOWUP "Slow up" #define TR_MIXES "MIXES" #define TR_CV "CV" +#define TR_VC "VIn" #if defined(PCBNV14) || defined(PCBPL18) #define TR_GV "GV" #else @@ -1171,8 +1172,10 @@ #define TR_MENU_TRIMS STR_CHAR_TRIM "Trims" #define TR_MENU_SWITCHES STR_CHAR_SWITCH "Switches" #define TR_MENU_LOGICAL_SWITCHES STR_CHAR_SWITCH "Logical switches" +#define TR_MENU_VIRTUAL_SWITCHES STR_CHAR_SWITCH "Virtual switches" #define TR_MENU_TRAINER STR_CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS STR_CHAR_CHANNEL "Channels" +#define TR_MENU_VCONTROL "Virtuals" #define TR_MENU_GVARS STR_CHAR_SLIDER "GVars" #define TR_MENU_TELEMETRY STR_CHAR_TELEMETRY "Telemetry" #define TR_MENU_DISPLAY "DISPLAY" diff --git a/radio/src/vcontrols.cpp b/radio/src/vcontrols.cpp new file mode 100644 index 00000000000..1b74f4ae0af --- /dev/null +++ b/radio/src/vcontrols.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + #include "vcontrols.h" + +#include "edgetx.h" + +#if defined(VCONTROLS) && defined(COLORLCD) +int16_t virtualInputs[MAX_VIRTUAL_INPUTS] = {}; +uint64_t virtualSwitches = 0; + +uint32_t activeVirtualInputs = 0; +uint64_t activeVirtualSwitches = 0; + +void resetVirtualControls() { + activeVirtualInputs = 0; + activeVirtualSwitches = 0; + virtualSwitches = 0; + for(auto& vin: virtualInputs) { + vin = 0; + } +} +#endif diff --git a/radio/src/vcontrols.h b/radio/src/vcontrols.h new file mode 100644 index 00000000000..cc6441f6b19 --- /dev/null +++ b/radio/src/vcontrols.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + #pragma once + +#include "dataconstants.h" + +#if defined(VCONTROLS) && defined(COLORLCD) +extern void resetVirtualControls(); + +extern int16_t virtualInputs[MAX_VIRTUAL_INPUTS]; +extern uint64_t virtualSwitches; + +extern uint32_t activeVirtualInputs; +extern uint64_t activeVirtualSwitches; +#endif