Merge pull request #289 from EdgeTX/2.4

Merge from 2.4 bug fixes
This commit is contained in:
richardclli
2021-06-21 15:45:44 +08:00
committed by GitHub
240 changed files with 3821 additions and 4760 deletions
+60 -13
View File
@@ -27,6 +27,28 @@
#include "api_colorlcd.h"
BitmapBuffer* luaLcdBuffer = nullptr;
static int8_t getTextHorizontalOffset(LcdFlags flags)
{
// no need to adjust if not right aligned
if (!(flags & RIGHT)) {
return 0;
}
const uint8_t font_index = FONT_INDEX(flags);
if (font_index >= sizeof(text_horizontal_offset)) {
return 0;
}
return text_horizontal_offset[font_index];
}
static int8_t getTextVerticalOffset(LcdFlags flags)
{
const uint8_t font_index = FONT_INDEX(flags);
if (font_index >= sizeof(text_vertical_offset)) {
return 0;
}
return text_vertical_offset[font_index];
}
/*luadoc
@function lcd.refresh()
@@ -60,7 +82,7 @@ Clear the LCD screen
static int luaLcdClear(lua_State * L)
{
if (luaLcdAllowed && luaLcdBuffer) {
LcdFlags color = luaL_optunsigned(L, 1, DEFAULT_BGCOLOR);
LcdFlags color = luaL_optunsigned(L, 1, DEFAULT_BGCOLOR_INDEX << 16u);
luaLcdBuffer->clear(COLOR(COLOR_VAL(color)));
}
return 0;
@@ -202,6 +224,10 @@ static int luaLcdDrawText(lua_State *L)
const char * s = luaL_checkstring(L, 3);
unsigned int att = luaL_optunsigned(L, 4, 0);
// apply text offsets, needed to align 2.4.x to 2.3.x font baselines
x += getTextHorizontalOffset(att);
y += getTextVerticalOffset(att);
bool shadowed = att & SHADOWED;
bool invers = (att & INVERS);
if (att & BLINK) invers = invers && !(BLINK_ON_PHASE);
@@ -217,8 +243,12 @@ static int luaLcdDrawText(lua_State *L)
if (invers) {
int height = getFontHeight(att & 0xFFFF);
int width = getTextWidth(s, 255, att);
int ix = x - INVERT_BOX_MARGIN;
if (att & RIGHT) {
ix = x - width - INVERT_BOX_MARGIN;
}
luaLcdBuffer->drawSolidFilledRect(
x - INVERT_BOX_MARGIN, y - INVERT_BOX_MARGIN,
ix, y - INVERT_BOX_MARGIN,
width + 2 * INVERT_BOX_MARGIN, height + 2 * INVERT_BOX_MARGIN,
FOCUS_BGCOLOR);
att = (att & 0xFFFF) | FOCUS_COLOR;
@@ -256,6 +286,10 @@ static int luaLcdDrawTimer(lua_State *L)
int seconds = luaL_checkinteger(L, 3);
unsigned int att = luaL_optunsigned(L, 4, 0);
// apply text offsets, needed to align 2.4.x to 2.3.x font baselines
x += getTextHorizontalOffset(att);
y += getTextVerticalOffset(att);
bool shadowed = att & SHADOWED;
att = (att & 0xFFFF) | COLOR(COLOR_VAL(att));
@@ -295,8 +329,30 @@ static int luaLcdDrawNumber(lua_State *L)
int val = luaL_checkinteger(L, 3);
unsigned int att = luaL_optunsigned(L, 4, 0);
bool invers = (att & INVERS);
att = (att & 0xFFFF) | COLOR(COLOR_VAL(att));
// apply text offsets, needed to align 2.4.x to 2.3.x font baselines
x += getTextHorizontalOffset(att);
y += getTextVerticalOffset(att);
char s[49];
BitmapBuffer::formatNumberAsString(s, 49, val, att & 0xFFFF);
if (invers) {
int height = getFontHeight(att & 0xFFFF);
int width = getTextWidth(s, 255, att);
int ix = x - INVERT_BOX_MARGIN;
if (att & RIGHT) {
ix = x - width - INVERT_BOX_MARGIN;
}
luaLcdBuffer->drawSolidFilledRect(
ix, y - INVERT_BOX_MARGIN,
width + 2 * INVERT_BOX_MARGIN, height + 2 * INVERT_BOX_MARGIN,
FOCUS_BGCOLOR);
att = (att & 0xFFFF) | FOCUS_COLOR;
}
if ((att & SHADOWED) && !(att & INVERS)) {
luaLcdBuffer->drawNumber(x, y, val, att & 0xFFFF);
}
@@ -664,9 +720,9 @@ static int luaLcdDrawGauge(lua_State *L)
int num = luaL_checkinteger(L, 5);
int den = luaL_checkinteger(L, 6);
unsigned int flags = luaL_optunsigned(L, 7, 0);
flags = (flags & 0xFFFF) | COLOR(COLOR_VAL(flags));
luaLcdBuffer->drawRect(x, y, w, h, 1, 0xff, flags);
uint8_t len = limit((uint8_t)1, uint8_t(w*num/den), uint8_t(w));
luaLcdBuffer->drawSolidFilledRect(x+1, y+1, len, h-2, flags);
@@ -727,9 +783,6 @@ Set a color for specific area
*/
static int luaLcdSetColor(lua_State *L)
{
if (!luaLcdAllowed)
return 0;
unsigned int index = luaL_checkunsigned(L, 1) >> 16;
unsigned int color = luaL_checkunsigned(L, 2);
@@ -750,9 +803,6 @@ Get the color for specific area : see lcd.setColor for area list
static int luaLcdGetColor(lua_State *L)
{
if (!luaLcdAllowed)
return 0;
unsigned int index = luaL_checkunsigned(L, 1) >> 16;
lua_pushunsigned(L, lcdColorTable[index]);
@@ -778,9 +828,6 @@ Returns a 5/6/5 rgb color code, that can be used with lcd.setColor
*/
static int luaRGB(lua_State *L)
{
if (!luaLcdAllowed)
return 0;
int r = luaL_checkinteger(L, 1);
int g = luaL_checkinteger(L, 2);
int b = luaL_checkinteger(L, 3);
+3
View File
@@ -33,5 +33,8 @@
constexpr coord_t INVERT_BOX_MARGIN = 2;
constexpr int8_t text_horizontal_offset[7] {-2,-1,-2,-2,-2,-2,-2};
constexpr int8_t text_vertical_offset[7] {2,2,0,2,3,3,7};
extern bool luaLcdAllowed;
extern BitmapBuffer * luaLcdBuffer;
+19 -23
View File
@@ -364,22 +364,20 @@ bool luaFindFieldByName(const char * name, LuaField & field, unsigned int flags)
// search in telemetry
field.desc[0] = '\0';
for (int i=0; i<MAX_TELEMETRY_SENSORS; i++) {
for (int i = 0; i < MAX_TELEMETRY_SENSORS; i++) {
if (isTelemetryFieldAvailable(i)) {
const char* sensorName = g_model.telemetrySensors[i].label;
if (!strncmp(sensorName, name, len)) {
if ((len <= TELEM_LABEL_LEN) && !strncmp(sensorName, name, len)) {
if (name[len] == '\0') {
field.id = MIXSRC_FIRST_TELEM + 3*i;
field.id = MIXSRC_FIRST_TELEM + 3 * i;
field.desc[0] = '\0';
return true;
}
else if (name[len] == '-' && name[len+1] == '\0') {
field.id = MIXSRC_FIRST_TELEM + 3*i + 1;
} else if (name[len] == '-' && name[len + 1] == '\0') {
field.id = MIXSRC_FIRST_TELEM + 3 * i + 1;
field.desc[0] = '\0';
return true;
}
else if (name[len] == '+' && name[len+1] == '\0') {
field.id = MIXSRC_FIRST_TELEM + 3*i + 2;
} else if (name[len] == '+' && name[len + 1] == '\0') {
field.id = MIXSRC_FIRST_TELEM + 3 * i + 2;
field.desc[0] = '\0';
return true;
}
@@ -923,7 +921,8 @@ static int luaGetFlightMode(lua_State * L)
}
lua_pushnumber(L, mode);
char name[sizeof(g_model.flightModeData[0].name)+1];
zchar2str(name, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[0].name));
strncpy(name, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[0].name));
name[sizeof(g_model.flightModeData[0].name)] = '\0';
lua_pushstring(L, name);
return 2;
}
@@ -1379,28 +1378,25 @@ static int luaSetTelemetryValue(lua_State * L)
uint32_t unit = luaL_optunsigned(L, 5, 0);
uint32_t prec = luaL_optunsigned(L, 6, 0);
char zname[4];
char name_buf[TELEM_LABEL_LEN]; // 4
const char* name = luaL_optstring(L, 7, NULL);
if (name != NULL && strlen(name) > 0) {
str2zchar(zname, name, 4);
}
else {
zname[0] = hex2zchar((id & 0xf000) >> 12);
zname[1] = hex2zchar((id & 0x0f00) >> 8);
zname[2] = hex2zchar((id & 0x00f0) >> 4);
zname[3] = hex2zchar((id & 0x000f) >> 0);
if (name == NULL || strlen(name) > 0) {
name_buf[0] = hex2char((id & 0xf000) >> 12);
name_buf[1] = hex2char((id & 0x0f00) >> 8);
name_buf[2] = hex2char((id & 0x00f0) >> 4);
name_buf[3] = hex2char((id & 0x000f) >> 0);
}
if (id | subId | instance) {
int index = setTelemetryValue(PROTOCOL_TELEMETRY_LUA, id, subId, instance, value, unit, prec);
int index = setTelemetryValue(PROTOCOL_TELEMETRY_LUA, id, subId, instance,
value, unit, prec);
if (index >= 0) {
TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index];
telemetrySensor.id = id;
telemetrySensor.subId = subId;
telemetrySensor.instance = instance;
telemetrySensor.init(zname, unit, prec);
telemetrySensor.init(name ? name: name_buf, unit, prec);
lua_pushboolean(L, true);
}
else {
} else {
lua_pushboolean(L, false);
}
return 1;
+19 -19
View File
@@ -39,9 +39,9 @@ Get current Model information
static int luaModelGetInfo(lua_State *L)
{
lua_newtable(L);
lua_pushtablestring(L, "name", g_model.header.name);
lua_pushtablenstring(L, "name", g_model.header.name);
#if LCD_DEPTH > 1
lua_pushtablestring(L, "bitmap", g_model.header.bitmap);
lua_pushtablenstring(L, "bitmap", g_model.header.bitmap);
#endif
return 1;
}
@@ -66,7 +66,7 @@ static int luaModelSetInfo(lua_State *L)
const char * key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(g_model.header.name, name, sizeof(g_model.header.name));
strncpy(g_model.header.name, name, sizeof(g_model.header.name));
#if defined(EEPROM)
memcpy(modelHeaders[g_eeGeneral.currModel].name, g_model.header.name, sizeof(g_model.header.name));
#endif
@@ -258,7 +258,7 @@ static int luaModelGetTimer(lua_State *L)
lua_pushtableinteger(L, "countdownBeep", timer.countdownBeep);
lua_pushtableboolean(L, "minuteBeep", timer.minuteBeep);
lua_pushtableinteger(L, "persistent", timer.persistent);
lua_pushtablestring(L, "name", timer.name);
lua_pushtablenstring(L, "name", timer.name);
}
else {
lua_pushnil(L);
@@ -310,7 +310,7 @@ static int luaModelSetTimer(lua_State *L)
}
if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(timer.name, name, sizeof(timer.name));
strncpy(timer.name, name, sizeof(timer.name));
}
}
storageDirty(EE_MODEL);
@@ -424,7 +424,7 @@ static int luaModelGetFlightMode(lua_State * L)
if (idx < MAX_FLIGHT_MODES) {
FlightModeData * fm = flightModeAddress(idx);
lua_newtable(L);
lua_pushtablestring(L, "name", fm->name);
lua_pushtablenstring(L, "name", fm->name);
lua_pushtableinteger(L, "switch", fm->swtch);
lua_pushtableinteger(L, "fadeIn", fm->fadeIn);
lua_pushtableinteger(L, "fadeOut", fm->fadeOut);
@@ -477,7 +477,7 @@ static int luaModelSetFlightMode(lua_State * L)
const char * key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(fm->name, name, sizeof(fm->name));
strncpy(fm->name, name, sizeof(fm->name));
}
else if (!strcmp(key, "switch")) {
fm->swtch = luaL_checkinteger(L, -1);
@@ -546,8 +546,8 @@ static int luaModelGetInput(lua_State *L)
if (idx < count) {
ExpoData * expo = expoAddress(first+idx);
lua_newtable(L);
lua_pushtablestring(L, "name", expo->name);
lua_pushtablestring(L, "inputName", g_model.inputNames[chn]);
lua_pushtablenstring(L, "name", expo->name);
lua_pushtablenstring(L, "inputName", g_model.inputNames[chn]);
lua_pushtableinteger(L, "source", expo->srcRaw);
lua_pushtableinteger(L, "weight", expo->weight);
lua_pushtableinteger(L, "offset", expo->offset);
@@ -599,11 +599,11 @@ static int luaModelInsertInput(lua_State *L)
const char * key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(expo->name, name, sizeof(expo->name));
strncpy(expo->name, name, sizeof(expo->name));
}
else if (!strcmp(key, "inputName")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(g_model.inputNames[chn], name, LEN_INPUT_NAME);
strncpy(g_model.inputNames[chn], name, LEN_INPUT_NAME);
}
else if (!strcmp(key, "source")) {
expo->srcRaw = luaL_checkinteger(L, -1);
@@ -773,7 +773,7 @@ static int luaModelGetMix(lua_State *L)
if (idx < count) {
MixData * mix = mixAddress(first+idx);
lua_newtable(L);
lua_pushtablestring(L, "name", mix->name);
lua_pushtablenstring(L, "name", mix->name);
lua_pushtableinteger(L, "source", mix->srcRaw);
lua_pushtableinteger(L, "weight", mix->weight);
lua_pushtableinteger(L, "offset", mix->offset);
@@ -827,7 +827,7 @@ static int luaModelInsertMix(lua_State *L)
const char * key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(mix->name, name, sizeof(mix->name));
strncpy(mix->name, name, sizeof(mix->name));
}
else if (!strcmp(key, "source")) {
mix->srcRaw = luaL_checkinteger(L, -1);
@@ -1043,7 +1043,7 @@ static int luaModelGetCurve(lua_State *L)
if (idx < MAX_CURVES) {
CurveHeader & CurveHeader = g_model.curves[idx];
lua_newtable(L);
lua_pushtablestring(L, "name", CurveHeader.name);
lua_pushtablenstring(L, "name", CurveHeader.name);
lua_pushtableinteger(L, "type", CurveHeader.type);
lua_pushtableboolean(L, "smooth", CurveHeader.smooth);
lua_pushtableinteger(L, "points", CurveHeader.points + 5);
@@ -1144,7 +1144,7 @@ static int luaModelSetCurve(lua_State *L)
const char *key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char *name = luaL_checkstring(L, -1);
str2zchar(newCurveHeader.name, name, sizeof(newCurveHeader.name));
strncpy(newCurveHeader.name, name, sizeof(newCurveHeader.name));
}
else if (!strcmp(key, "type")) {
newCurveHeader.type = luaL_checkinteger(L, -1);
@@ -1301,7 +1301,7 @@ static int luaModelGetCustomFunction(lua_State *L)
lua_pushtableinteger(L, "switch", CFN_SWITCH(cfn));
lua_pushtableinteger(L, "func", CFN_FUNC(cfn));
if (CFN_FUNC(cfn) == FUNC_PLAY_TRACK || CFN_FUNC(cfn) == FUNC_BACKGND_MUSIC || CFN_FUNC(cfn) == FUNC_PLAY_SCRIPT) {
lua_pushtablestring(L, "name", cfn->play.name);
lua_pushtablenstring(L, "name", cfn->play.name);
}
else {
lua_pushtableinteger(L, "value", cfn->all.val);
@@ -1398,7 +1398,7 @@ static int luaModelGetOutput(lua_State *L)
if (idx < MAX_OUTPUT_CHANNELS) {
LimitData * limit = limitAddress(idx);
lua_newtable(L);
lua_pushtablestring(L, "name", limit->name);
lua_pushtablenstring(L, "name", limit->name);
lua_pushtableinteger(L, "min", limit->min-1000);
lua_pushtableinteger(L, "max", limit->max+1000);
lua_pushtableinteger(L, "offset", limit->offset);
@@ -1440,7 +1440,7 @@ static int luaModelSetOutput(lua_State *L)
const char * key = luaL_checkstring(L, -2);
if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
str2zchar(limit->name, name, sizeof(limit->name));
strncpy(limit->name, name, sizeof(limit->name));
}
else if (!strcmp(key, "min")) {
limit->min = luaL_checkinteger(L, -1)+1000;
@@ -1558,7 +1558,7 @@ static int luaModelGetSensor(lua_State *L)
TelemetrySensor & sensor = g_model.telemetrySensors[idx];
lua_newtable(L);
lua_pushtableinteger(L, "type", sensor.type);
lua_pushtablestring(L, "name", sensor.label);
lua_pushtablenstring(L, "name", sensor.label);
lua_pushtableinteger(L, "unit", sensor.unit);
lua_pushtableinteger(L, "prec", sensor.prec);
if (sensor.type == TELEM_TYPE_CUSTOM) {
+16
View File
@@ -62,7 +62,20 @@ void luaInitThemesAndWidgets();
#define lua_pushtableboolean(L, k, v) (lua_pushstring(L, (k)), lua_pushboolean(L, (v)), lua_settable(L, -3))
#define lua_pushtableinteger(L, k, v) (lua_pushstring(L, (k)), lua_pushinteger(L, (v)), lua_settable(L, -3))
#define lua_pushtablenumber(L, k, v) (lua_pushstring(L, (k)), lua_pushnumber(L, (v)), lua_settable(L, -3))
// size based string (possibly no null-termination)
#define __lua_strncpy(s) \
char tmp[sizeof(s) + 1]; \
strncpy(tmp, (s), sizeof(tmp) - 1); \
tmp[sizeof(s)] = '\0';
// size based string (possibly no null-termination)
#define lua_pushnstring(L, s) { __lua_strncpy(s); lua_pushstring(L, tmp); }
#define lua_pushtablenstring(L, k, v) { __lua_strncpy(v); lua_pushstring(L, (k)); lua_pushstring(L, tmp); lua_settable(L, -3); }
// null-terminated string
#define lua_pushtablestring(L, k, v) (lua_pushstring(L, (k)), lua_pushstring(L, (v)), lua_settable(L, -3))
#define lua_registerlib(L, name, tab) (luaL_newmetatable(L, name), luaL_setfuncs(L, tab, 0), lua_setglobal(L, name))
#define RUN_MIX_SCRIPT (1 << 0)
@@ -174,6 +187,9 @@ void registerBitmapClass(lua_State * L);
void luaSetInstructionsLimit(lua_State* L, int count);
int luaLoadScriptFileToState(lua_State * L, const char * filename, const char * mode);
// Unregister LUA widget factories
void luaUnregisterWidgets();
#if LCD_W > 350
#define RADIO_TOOL_NAME_MAXLEN 40
#else
+15
View File
@@ -225,6 +225,11 @@ class LuaWidgetFactory: public WidgetFactory
{
}
~LuaWidgetFactory()
{
unregisterWidget(this);
}
Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init=true) const override
{
if (lsWidgets == 0) return 0;
@@ -507,3 +512,13 @@ void luaInitThemesAndWidgets()
luaDoGc(lsWidgets, true);
}
}
void luaUnregisterWidgets()
{
std::list<const WidgetFactory *> regWidgets(getRegisteredWidgets());
for (auto w : regWidgets) {
if (dynamic_cast<const LuaWidgetFactory*>(w)) {
delete w;
}
}
}