diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 1553e22fea3..aae3f3accb7 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -72,6 +72,7 @@ if(PCB STREQUAL X7 AND PCBREV STREQUAL LR3PRO) else() option(POWER_LED_BLUE "Override Power LED to be normally Blue" OFF) endif() +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).") @@ -446,6 +447,10 @@ else(SIZE_TARGET_MEM_DEFINE MATCHES 8192) add_definitions(-DSDRAM_8M) endif() +if(VCONTROLS) + add_definitions(-DVCONTROLS) +endif() + set(SRC ${SRC} edgetx.cpp @@ -516,6 +521,9 @@ if(ALL_LANGUAGES) translations/sim/lang_ua.cpp ) 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 9b6681a9223..ec1a0e95dc9 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -59,6 +59,8 @@ #define MAX_TELEMETRY_SENSORS 60 #endif #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 @@ -437,6 +439,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, @@ -479,6 +486,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_TIMER = 1 << 17, SRC_TELEM = 1 << 18, SRC_LIGHT = 1 << 19, + SRC_VCONTROL = 1 << 21, SRC_NONE = 1 << 30, SRC_INVERT = 1 << 31, }; diff --git a/radio/src/gui/colorlcd/controls/sourcechoice.cpp b/radio/src/gui/colorlcd/controls/sourcechoice.cpp index 8fca34d1f4e..e5fab1f6b24 100644 --- a/radio/src/gui/colorlcd/controls/sourcechoice.cpp +++ b/radio/src/gui/colorlcd/controls/sourcechoice.cpp @@ -80,6 +80,10 @@ class SourceChoiceMenuToolbar : public MenuToolbar nullptr, STR_MENU_TRAINER); addButton(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(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 eb88917794a..b70deab75d9 100644 --- a/radio/src/gui/colorlcd/controls/switchchoice.cpp +++ b/radio/src/gui/colorlcd/controls/switchchoice.cpp @@ -36,6 +36,10 @@ class SwitchChoiceMenuToolbar : public MenuToolbar STR_MENU_TRIMS); addButton("LS", SWSRC_FIRST_LOGICAL_SWITCH, SWSRC_LAST_LOGICAL_SWITCH, nullptr, STR_MENU_LOGICAL_SWITCHES); +#if defined(VCONTROLS) + addButton("VS", SWSRC_FIRST_VIRTUAL_SWITCH, SWSRC_LAST_VIRTUAL_SWITCH, + nullptr, STR_MENU_VIRTUAL_SWITCHES); +#endif addButton("FM", SWSRC_FIRST_FLIGHT_MODE, SWSRC_LAST_FLIGHT_MODE, nullptr, STR_FLIGHT_MODE); addButton(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 e8b1186a6a4..51f2c37f425 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -29,6 +29,10 @@ #include "mixes.h" #include "os/sleep.h" +#if defined(VCONTROLS) && defined(COLORLCD) +#include "vcontrols.h" +#endif + #undef CPN #include "MultiSubtypeDefs.h" @@ -223,7 +227,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(); @@ -279,6 +291,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 }, @@ -302,7 +317,7 @@ bool checkSourceAvailable(int source, uint32_t sourceTypes) #define SRC_COMMON \ SRC_STICK | SRC_POT | SRC_TILT | SRC_LIGHT | 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) { @@ -367,7 +382,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; @@ -457,6 +479,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)) @@ -482,6 +511,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 3792c627dbe..c080652392e 100644 --- a/radio/src/lua/api_colorlcd_lvgl.cpp +++ b/radio/src/lua/api_colorlcd_lvgl.cpp @@ -519,6 +519,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 dddda874642..81d94c0c4f4 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -62,6 +62,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 @@ -2480,6 +2485,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}; @@ -3180,6 +3268,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 9aa7f3782b3..8134efa0b98 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" @@ -494,7 +495,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)); @@ -503,7 +508,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 ab9c77a2953..867c7d10062 100644 --- a/radio/src/storage/storage_common.cpp +++ b/radio/src/storage/storage_common.cpp @@ -29,6 +29,9 @@ #if defined(FUNCTION_SWITCHES_RGB_LEDS) #include "hal/rgbleds.h" #endif +#if defined(VCONTROLS) && defined(COLORLCD) +#include "vcontrols.h" +#endif #if defined(COLORLCD) #include "view_main.h" @@ -278,6 +281,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' && @@ -399,6 +411,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) { @@ -1426,6 +1448,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' @@ -1492,7 +1522,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 ec16dcb34f5..71b49c2b093 100644 --- a/radio/src/strhelpers.cpp +++ b/radio/src/strhelpers.cpp @@ -501,6 +501,10 @@ char *getSwitchPositionName(char *dest, swsrc_t idx, bool defaultOnly) } 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) { + strAppendStringWithIndex(s, STR_VSW, idx - SWSRC_FIRST_VIRTUAL_SWITCH + 1); +#endif } else if (idx <= SWSRC_ONE) { idx -= SWSRC_ON; getStringAtIndex(s, STR_ON_ONE_SWITCHES, idx); @@ -775,7 +779,13 @@ char *getSourceString(char (&destRef)[L], mixsrc_t idx, bool defaultOnly) } 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(COLORLCD) char *s = strAppendStringWithIndex(dest, STR_GV, idx + 1); diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 8f7327ef73d..77e12a821e6 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -31,6 +31,9 @@ #include "input_mapping.h" #include "inactivity_timer.h" #include "tasks/mixer_task.h" +#if defined(VCONTROLS) +#include "vcontrols.h" +#endif #if defined(RADIO_GX12) #include "targets/taranis/gx12/bsp_io.h" @@ -761,6 +764,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/i18n/cn.h b/radio/src/translations/i18n/cn.h index 73f816be2a5..3cf968eb73e 100644 --- a/radio/src/translations/i18n/cn.h +++ b/radio/src/translations/i18n/cn.h @@ -94,6 +94,10 @@ #define TR_MIXES "混控" #define TR_MENU_GLOBAL_VARS "全局变量" #define TR_MENULOGICALSWITCHES "逻辑开关" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENUCUSTOMFUNC "特殊功能" #define TR_MENUCUSTOMSCRIPTS "自定义脚本" #define TR_MENUTELEMETRY "遥测/回传" diff --git a/radio/src/translations/i18n/cz.h b/radio/src/translations/i18n/cz.h index ec1405eb494..1171a596bc4 100644 --- a/radio/src/translations/i18n/cz.h +++ b/radio/src/translations/i18n/cz.h @@ -663,6 +663,10 @@ #define TR_MENUCURVE "\002K" #define TR_MENULOGICALSWITCH "LOG. SPÍNAČ" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENUSTAT "STATISTIKA" #define TR_MENUDEBUG "DIAG" #define TR_MONITOR_CHANNELS "MONITOR KANÁLŮ %d/%d" diff --git a/radio/src/translations/i18n/da.h b/radio/src/translations/i18n/da.h index 1d5ddff0182..0e608a440ac 100644 --- a/radio/src/translations/i18n/da.h +++ b/radio/src/translations/i18n/da.h @@ -1252,6 +1252,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trim" #define TR_MENU_SWITCHES CHAR_SWITCH "Kontakter" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Logiske funktioner" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Træner" #define TR_MENU_CHANNELS CHAR_CHANNEL "Kanaler" #define TR_MENU_GVARS CHAR_SLIDER "Globale Var" diff --git a/radio/src/translations/i18n/de.h b/radio/src/translations/i18n/de.h index ace346fae3e..411332f5db3 100644 --- a/radio/src/translations/i18n/de.h +++ b/radio/src/translations/i18n/de.h @@ -524,6 +524,8 @@ #define TR_SLOWDOWN "Langs.Ab" #define TR_SLOWUP "Langs.Auf" #define TR_CV "KV" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_GV TR("G", "GV") #define TR_RANGE TR("Bereich", "Variobereich m/s") #define TR_CENTER TR("Mitte", "Variomitte m/s") @@ -1245,6 +1247,8 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trimmung" #define TR_MENU_SWITCHES CHAR_SWITCH "Schalter" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Log. Schalter" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. Schalter" +#define TR_MENU_VCONTROL "Virtuals" #define TR_MENU_TRAINER CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS CHAR_CHANNEL "Kanäle" #define TR_MENU_GVARS CHAR_SLIDER "Glob. Vars" diff --git a/radio/src/translations/i18n/en.h b/radio/src/translations/i18n/en.h index 8660c420635..70abbca3fbe 100644 --- a/radio/src/translations/i18n/en.h +++ b/radio/src/translations/i18n/en.h @@ -524,6 +524,8 @@ #define TR_SLOWDOWN TR("Slow dn", "Slow down") #define TR_SLOWUP "Slow up" #define TR_CV "CV" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_GV TR("G", "GV") #define TR_RANGE "Range" #define TR_CENTER "Center" @@ -1246,6 +1248,8 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trims" #define TR_MENU_SWITCHES CHAR_SWITCH "Switches" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Logical switches" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" #define TR_MENU_TRAINER CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS CHAR_CHANNEL "Channels" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/es.h b/radio/src/translations/i18n/es.h index 47a4680aa62..ea19808f33d 100644 --- a/radio/src/translations/i18n/es.h +++ b/radio/src/translations/i18n/es.h @@ -1247,6 +1247,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trims" #define TR_MENU_SWITCHES CHAR_SWITCH "Interruptores" #define TR_MENU_LOGICAL_SWITCHES TR( CHAR_SWITCH "Interr. lógicos", CHAR_SWITCH "Interruptores lógicos") +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Entrenador" #define TR_MENU_CHANNELS CHAR_CHANNEL "Canales" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/fi.h b/radio/src/translations/i18n/fi.h index 8383da19531..153cc1f7ebe 100644 --- a/radio/src/translations/i18n/fi.h +++ b/radio/src/translations/i18n/fi.h @@ -1247,6 +1247,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trims" #define TR_MENU_SWITCHES CHAR_SWITCH "Switches" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Logical Switches" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS CHAR_CHANNEL "Channels" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/fr.h b/radio/src/translations/i18n/fr.h index 7d9ce687e4c..1d9cbec165f 100644 --- a/radio/src/translations/i18n/fr.h +++ b/radio/src/translations/i18n/fr.h @@ -1249,6 +1249,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trims" #define TR_MENU_SWITCHES CHAR_SWITCH "Inters" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Inters logiques" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Écolage" #define TR_MENU_CHANNELS CHAR_CHANNEL "Canaux" #define TR_MENU_GVARS CHAR_SLIDER "Var. Glob." @@ -1263,6 +1267,9 @@ #define TR_AUTH_FAILURE "Échec authentification" #define TR_RACING_MODE "Mode Racing" +// #undef STR_SENSOR_BATT +// #define STR_SENSOR_BATT "BtRx" + // The following content is Untranslated) #define TR_USE_THEME_COLOR "Utiliser couleur du thème" diff --git a/radio/src/translations/i18n/he.h b/radio/src/translations/i18n/he.h index 9687f57f6ca..7380681ae08 100644 --- a/radio/src/translations/i18n/he.h +++ b/radio/src/translations/i18n/he.h @@ -1248,6 +1248,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "קיזוזים" #define TR_MENU_SWITCHES CHAR_SWITCH "מתגים" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "מתגים לוגים" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "טריינר" #define TR_MENU_CHANNELS CHAR_CHANNEL "עורצים" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/it.h b/radio/src/translations/i18n/it.h index 4c8ab8e4a33..df2f6cd5379 100644 --- a/radio/src/translations/i18n/it.h +++ b/radio/src/translations/i18n/it.h @@ -1243,8 +1243,12 @@ #define TR_MENU_MAX CHAR_FUNCTION "MAX" #define TR_MENU_HELI CHAR_CYC "Ciclico" #define TR_MENU_TRIMS CHAR_TRIM "Trims" -#define TR_MENU_SWITCHES CHAR_SWITCH "Switch" -#define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Switch logici" +#define TR_MENU_SWITCHES CHAR_SWITCH "Interrut." +#define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Interrut. Logici" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS CHAR_CHANNEL "Canali" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/jp.h b/radio/src/translations/i18n/jp.h index c3d1f79e252..88140abf21b 100644 --- a/radio/src/translations/i18n/jp.h +++ b/radio/src/translations/i18n/jp.h @@ -1244,6 +1244,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "トリム" #define TR_MENU_SWITCHES CHAR_SWITCH "スイッチ" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "論理スイッチ" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "トレーナー" #define TR_MENU_CHANNELS CHAR_CHANNEL "チャンネル" #define TR_MENU_GVARS CHAR_SLIDER "グローバル変数" diff --git a/radio/src/translations/i18n/ko.h b/radio/src/translations/i18n/ko.h index 53fe6352943..7fb2386647f 100644 --- a/radio/src/translations/i18n/ko.h +++ b/radio/src/translations/i18n/ko.h @@ -1291,6 +1291,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "트림" #define TR_MENU_SWITCHES CHAR_SWITCH "스위치" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "로직 스위치" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "트레이너" #define TR_MENU_CHANNELS CHAR_CHANNEL "채널" #define TR_MENU_GVARS CHAR_SLIDER "GVAR" diff --git a/radio/src/translations/i18n/nl.h b/radio/src/translations/i18n/nl.h index b8714dfb812..24dac6f0a5d 100644 --- a/radio/src/translations/i18n/nl.h +++ b/radio/src/translations/i18n/nl.h @@ -1248,6 +1248,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trims" #define TR_MENU_SWITCHES CHAR_SWITCH "Schakelaars" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Log. Schakelaars" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS CHAR_CHANNEL "Kanalen" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/pl.h b/radio/src/translations/i18n/pl.h index 6868d6cf078..2b24c12edf3 100644 --- a/radio/src/translations/i18n/pl.h +++ b/radio/src/translations/i18n/pl.h @@ -1245,6 +1245,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trymy" #define TR_MENU_SWITCHES CHAR_SWITCH "Przełączniki" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Przełączn.logicz" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Trener " #define TR_MENU_CHANNELS CHAR_CHANNEL "Kanały " #define TR_MENU_GVARS CHAR_SLIDER "Zmienne glob." diff --git a/radio/src/translations/i18n/pt.h b/radio/src/translations/i18n/pt.h index 77b6bf1ee71..eaa89575cfa 100644 --- a/radio/src/translations/i18n/pt.h +++ b/radio/src/translations/i18n/pt.h @@ -1246,6 +1246,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trims" #define TR_MENU_SWITCHES CHAR_SWITCH "Chaves" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Chaves Lógicas" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Trainer" #define TR_MENU_CHANNELS CHAR_CHANNEL "Canais" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/ru.h b/radio/src/translations/i18n/ru.h index a5cb6e624f2..420fa20d1ef 100644 --- a/radio/src/translations/i18n/ru.h +++ b/radio/src/translations/i18n/ru.h @@ -1247,6 +1247,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Триммеры" #define TR_MENU_SWITCHES CHAR_SWITCH "Тумблеры" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Логич тумблеры" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Тренажер" #define TR_MENU_CHANNELS CHAR_CHANNEL "Каналы" #define TR_MENU_GVARS CHAR_SLIDER "Глоб перем" diff --git a/radio/src/translations/i18n/se.h b/radio/src/translations/i18n/se.h index 5ce85caa9ae..ad443dfc108 100644 --- a/radio/src/translations/i18n/se.h +++ b/radio/src/translations/i18n/se.h @@ -1260,6 +1260,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Trimm" #define TR_MENU_SWITCHES CHAR_SWITCH "Brytare" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Logiska brytare" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Lärare" #define TR_MENU_CHANNELS CHAR_CHANNEL "Kanaler" #define TR_MENU_GVARS CHAR_SLIDER "GVars" diff --git a/radio/src/translations/i18n/tw.h b/radio/src/translations/i18n/tw.h index 16216abd063..08635ccf870 100644 --- a/radio/src/translations/i18n/tw.h +++ b/radio/src/translations/i18n/tw.h @@ -1243,6 +1243,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "微調" #define TR_MENU_SWITCHES CHAR_SWITCH "開關" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "邏輯開關" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "教練" #define TR_MENU_CHANNELS CHAR_CHANNEL "通道" #define TR_MENU_GVARS CHAR_SLIDER "全局變量" diff --git a/radio/src/translations/i18n/ua.h b/radio/src/translations/i18n/ua.h index 90e1465c6ff..a1b2bc04d98 100644 --- a/radio/src/translations/i18n/ua.h +++ b/radio/src/translations/i18n/ua.h @@ -1246,6 +1246,10 @@ #define TR_MENU_TRIMS CHAR_TRIM "Трими" #define TR_MENU_SWITCHES CHAR_SWITCH "Перемикачі" #define TR_MENU_LOGICAL_SWITCHES CHAR_SWITCH "Логічні перемикачі" +#define TR_MENU_VIRTUAL_SWITCHES CHAR_SWITCH "Virt. switches" +#define TR_MENU_VCONTROL "Virtuals" +#define TR_VC "VIn" +#define TR_VSW "VS" #define TR_MENU_TRAINER CHAR_TRAINER "Тренер" #define TR_MENU_CHANNELS CHAR_CHANNEL "Канали" #define TR_MENU_GVARS CHAR_SLIDER "ГлобЗмін" diff --git a/radio/src/translations/sim_string_list.h b/radio/src/translations/sim_string_list.h index 5fdac83b04b..4a8a2511960 100644 --- a/radio/src/translations/sim_string_list.h +++ b/radio/src/translations/sim_string_list.h @@ -652,6 +652,8 @@ #define STR_MENU_INPUTS currentLangStrings->STR_MENU_INPUTS #define STR_MENU_INVERT currentLangStrings->STR_MENU_INVERT #define STR_MENU_LOGICAL_SWITCHES currentLangStrings->STR_MENU_LOGICAL_SWITCHES +#define STR_MENU_VIRTUAL_SWITCHES currentLangStrings->STR_MENU_VIRTUAL_SWITCHES +#define STR_MENU_VCONTROL currentLangStrings->STR_MENU_VCONTROL #define STR_MENU_LUA currentLangStrings->STR_MENU_LUA #define STR_MENU_MAX currentLangStrings->STR_MENU_MAX #define STR_MENU_MIN currentLangStrings->STR_MENU_MIN @@ -1056,6 +1058,7 @@ #define STR_V2 currentLangStrings->STR_V2 #define STR_VALUE currentLangStrings->STR_VALUE #define STR_VARIO currentLangStrings->STR_VARIO +#define STR_VC currentLangStrings->STR_VC #define STR_VIEW_CHANNELS currentLangStrings->STR_VIEW_CHANNELS #define STR_VIEW_NOTES currentLangStrings->STR_VIEW_NOTES #define STR_VIEW_TEXT currentLangStrings->STR_VIEW_TEXT @@ -1083,6 +1086,7 @@ #define STR_VOICE_UKRAINIAN currentLangStrings->STR_VOICE_UKRAINIAN #define STR_VOLTAGE currentLangStrings->STR_VOLTAGE #define STR_VOLUME currentLangStrings->STR_VOLUME +#define STR_VSW currentLangStrings->STR_VSW #define STR_VTRIM currentLangStrings->STR_VTRIM #define STR_WAITING_FOR_MODULE currentLangStrings->STR_WAITING_FOR_MODULE #define STR_WAITING_FOR_RX currentLangStrings->STR_WAITING_FOR_RX diff --git a/radio/src/translations/string_list.h b/radio/src/translations/string_list.h index 146fcf84716..b1e18d0f093 100644 --- a/radio/src/translations/string_list.h +++ b/radio/src/translations/string_list.h @@ -112,6 +112,11 @@ STR(MAIN_MENU_STATISTICS) STR(MAIN_MENU_THEMES) STR(MAIN_MODEL_SETTINGS) STR(MAIN_RADIO_SETTINGS) +#if defined(VCONTROLS) +STR(MENU_VCONTROL) +STR(MENU_VIRTUAL_SWITCHES) +#endif +// STR(MANAGE_MODELS) STR(MEM_USED_EXTRA) STR(MEM_USED_SCRIPT) STR(MEM_USED_WIDGET) @@ -263,7 +268,6 @@ STRARRAY(LIMITS_HEADERS) STRARRAY(LSW_HEADERS) STRARRAY(PHASES_HEADERS) #endif - STR(AXISDIR) STR(MENUAXISDIR) STR(MENUTOSTART) @@ -1083,6 +1087,10 @@ STR(VOICE_TAIWANESE) STR(VOICE_UKRAINIAN) STR(VOLTAGE) STR(VOLUME) +#if defined(VCONTROLS) +STR(VC) +STR(VSW) +#endif STR(VTRIM) STR(WAITING_FOR_MODULE) STR(WAITING_FOR_RX) 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