Files
edgetx-gx12/companion/src/firmwares/edgetx/yaml_rawsource.cpp
T
RistoGitHubNiel Horne (elecpower), Raphael Coeffic (raphaelcoeffic) and Peter Feerick (pfeerick).
9dc4065525 feat: Add support for SpaceMouse mod (6D input knob) (#1853)
Use `-DSPACEMOUSE=YES` CMake option to activate on Horus color targets.
Co-authored-by: Niel Horne (elecpower), Raphael Coeffic (raphaelcoeffic) and Peter Feerick (pfeerick).
2022-09-18 09:23:48 +02:00

308 lines
8.1 KiB
C++

/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "yaml_rawsource.h"
#include "eeprominterface.h"
static const YamlLookupTable spacemouseLut = {
{ 0, "SPACEMOUSE_A" },
{ 1, "SPACEMOUSE_B" },
{ 2, "SPACEMOUSE_C" },
{ 3, "SPACEMOUSE_D" },
{ 4, "SPACEMOUSE_E" },
{ 5, "SPACEMOUSE_F" },
};
std::string YamlRawSourceEncode(const RawSource& rhs)
{
std::string src_str;
char c = 'A';
switch (rhs.type) {
case SOURCE_TYPE_VIRTUAL_INPUT:
src_str += "I" + std::to_string(rhs.index);
break;
case SOURCE_TYPE_LUA_OUTPUT:
src_str += "lua(";
src_str += std::to_string(rhs.index / 16);
src_str += ",";
src_str += std::to_string(rhs.index % 16);
src_str += ")";
break;
case SOURCE_TYPE_STICK:
src_str = getCurrentFirmware()->getAnalogInputTag(rhs.index);
break;
case SOURCE_TYPE_TRIM:
src_str = getCurrentFirmware()->getTrimSourcesTag(rhs.index);
break;
case SOURCE_TYPE_MAX:
src_str += "MAX";
break;
case SOURCE_TYPE_SWITCH:
src_str += getCurrentFirmware()->getSwitchesTag(rhs.index);
break;
case SOURCE_TYPE_CUSTOM_SWITCH:
src_str += "ls(";
src_str += std::to_string(rhs.index + 1);
src_str += ")";
break;
case SOURCE_TYPE_FUNCTIONSWITCH:
if (IS_JUMPER_TPRO(getCurrentBoard())) {
c += Boards::getCapability(getCurrentBoard(), Board::Switches);
c += rhs.index;
src_str += "S";
src_str += c;
}
break;
case SOURCE_TYPE_CYC:
src_str = getCurrentFirmware()->getRawSourceCyclicTag(rhs.index);
break;
case SOURCE_TYPE_PPM:
src_str += "tr(";
src_str += std::to_string(rhs.index);
src_str += ")";
break;
case SOURCE_TYPE_CH:
src_str += "ch(";
src_str += std::to_string(rhs.index);
src_str += ")";
break;
case SOURCE_TYPE_GVAR:
src_str += "gv(";
src_str += std::to_string(rhs.index);
src_str += ")";
break;
case SOURCE_TYPE_SPECIAL:
src_str = getCurrentFirmware()->getRawSourceSpecialTypesTag(rhs.index);
break;
case SOURCE_TYPE_TELEMETRY:
src_str = "tele(";
switch (rhs.index % 3) {
case 0:
break;
case 1:
src_str += '-';
break;
case 2:
src_str += '+';
break;
}
src_str += std::to_string(rhs.index / 3);
src_str += ")";
break;
case SOURCE_TYPE_SPACEMOUSE:
src_str = "SPACEMOUSE_";
c += rhs.index;
src_str += c;
break;
default:
src_str = "NONE";
break;
}
return src_str;
}
RawSource YamlRawSourceDecode(const std::string& src_str)
{
RawSource rhs;
const char* val = src_str.data();
size_t val_len = src_str.size();
if (val_len > 1 && val[0] == 'I'
&& (val[1] >= '0') && (val[1] <= '9')) {
int idx = std::stoi(src_str.substr(1));
if (idx < CPN_MAX_INPUTS) {
rhs = RawSource(SOURCE_TYPE_VIRTUAL_INPUT, idx);
}
} else if (val_len == 2
&& val[0] == 'S'
&& val[1] >= 'A'
&& val[1] <= 'Z') {
int idx = getCurrentFirmware()->getSwitchesIndex(src_str.c_str());
if (idx >= 0 && idx < CPN_MAX_SWITCHES) {
rhs = RawSource(SOURCE_TYPE_SWITCH, idx);
} else if (IS_JUMPER_TPRO(getCurrentBoard())) {
int numSw = Boards::getCapability(getCurrentBoard(), Board::Switches);
idx = val[1] - 'A';
idx -= numSw;
if(idx >= 0 and idx < Boards::getCapability(getCurrentBoard(), Board::FunctionSwitches)) {
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, idx);
}
}
} else if (val_len > 4 &&
val[0] == 'l' &&
val[1] == 'u' &&
val[2] == 'a' &&
val[3] == '(') {
std::stringstream src(src_str.substr(4));
int script = 0, output = 0; // TODO: check rename outputs to inputs???
src >> script;
src.ignore();
src >> output;
if (script < CPN_MAX_SCRIPTS && output < CPN_MAX_SCRIPT_INPUTS)
rhs = RawSource(SOURCE_TYPE_LUA_OUTPUT, script * 16 + output);
} else if (val_len > 3 &&
val[0] == 'l' &&
val[1] == 's' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
int ls = 0;
src >> ls;
if (ls > 0 && ls <= CPN_MAX_LOGICAL_SWITCHES)
rhs = RawSource(SOURCE_TYPE_CUSTOM_SWITCH, ls - 1);
} else if (val_len > 3 &&
val[0] == 'f' &&
val[1] == 's' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
int fs = 0;
src >> fs;
if (fs > 0 && fs <= CPN_MAX_FUNCTION_SWITCHES)
rhs = RawSource(SOURCE_TYPE_FUNCTIONSWITCH, fs - 1);
} else if (val_len > 3 &&
val[0] == 't' &&
val[1] == 'r' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
int tr = 0;
src >> tr;
if (tr < getCurrentFirmware()->getCapability(TrainerInputs))
rhs = RawSource(SOURCE_TYPE_PPM, tr);
} else if (val_len > 3 &&
val[0] == 'c' &&
val[1] == 'h' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
int ch = 0;
src >> ch;
if (ch < CPN_MAX_CHNOUT)
rhs = RawSource(SOURCE_TYPE_CH, ch);
} else if (val_len > 3 &&
val[0] == 'g' &&
val[1] == 'v' &&
val[2] == '(') {
std::stringstream src(src_str.substr(3));
int gv = 0;
src >> gv;
if (gv < CPN_MAX_GVARS)
rhs = RawSource(SOURCE_TYPE_GVAR, gv);
} else if (val_len > 5 &&
val[0] == 't' &&
val[1] == 'e' &&
val[2] == 'l' &&
val[3] == 'e' &&
val[4] == '(') {
std::stringstream src(src_str.substr(5));
// parse sign
uint8_t sign = 0;
char c = src.peek();
if (c == '-') {
sign = 1;
src.ignore();
} else if (c == '+') {
sign = 2;
src.ignore();
}
int sensor = 0;
src >> sensor;
if (sensor < CPN_MAX_SENSORS)
rhs = RawSource(SOURCE_TYPE_TELEMETRY, sensor * 3 + sign);
} else {
YAML::Node node(src_str);
std::string ana_str;
node >> ana_str;
int ana_idx = getCurrentFirmware()->getAnalogInputIndex(ana_str.c_str());
if (ana_idx >= 0) {
rhs.type = SOURCE_TYPE_STICK;
rhs.index = ana_idx;
}
int trm_idx = getCurrentFirmware()->getTrimSourcesIndex(src_str.c_str());
if (trm_idx >= 0) {
rhs.type = SOURCE_TYPE_TRIM;
rhs.index = trm_idx;
}
int cyc_idx = getCurrentFirmware()->getRawSourceCyclicIndex(src_str.c_str());
if (cyc_idx >= 0) {
rhs.type = SOURCE_TYPE_CYC;
rhs.index = cyc_idx;
}
int sp_idx = getCurrentFirmware()->getRawSourceSpecialTypesIndex(src_str.c_str());
if (sp_idx >= 0) {
rhs.type = SOURCE_TYPE_SPECIAL;
rhs.index = sp_idx;
}
if (node.IsScalar() && node.as<std::string>().size() == 12 && node.as<std::string>().substr(0, 11) == "SPACEMOUSE_") {
int sm_idx;
node >> spacemouseLut >> sm_idx;
if (sm_idx >= 0) {
rhs.type = SOURCE_TYPE_SPACEMOUSE;
rhs.index = sm_idx;
}
}
if (node.IsScalar() && node.as<std::string>() == "MAX") {
rhs.type = SOURCE_TYPE_MAX;
rhs.index = 0;
}
}
return rhs;
}
namespace YAML {
Node convert<RawSource>::encode(const RawSource& rhs)
{
return Node(YamlRawSourceEncode(rhs));
}
bool convert<RawSource>::decode(const Node& node, RawSource& rhs)
{
std::string src_str = node.Scalar();
rhs = YamlRawSourceDecode(src_str);
return true;
}
} // namespace YAML