feat(lua): Add several Lua API funcs and constants (#2279)

* LUA: Add Bitmap.toMask and lcd.drawBitmapPattern functions

* LUA: Add lcd.invertRect function

* LUA: Add Bitmap.resize function

* LUA: Add getOutputValue function

* LUA: Add timer showElapsed configuration

* LUA: Add model extendedLimits configuration

* LUA: Add some global constants

* Add model jitterFilter configuration

* Add model.getSwashRing and setSwashRing functions
This commit is contained in:
David PHAM-VAN
2022-09-08 20:03:58 +10:00
committed by GitHub
parent ab640e3055
commit 155a854131
3 changed files with 327 additions and 6 deletions
+189
View File
@@ -588,6 +588,84 @@ static int luaGetBitmapSize(lua_State * L)
return 2;
}
/*luadoc
@function Bitmap.resize(bitmap, width, height)
Return a resized bitmap object
@param bitmap (pointer) point to a bitmap previously opened with Bitmap.open()
@param width (number) the new bitmap width
@param height (number) the new bitmap height
@notice Only available on Horus
@status current Introduced in 2.8.0
*/
static int luaBitmapResize(lua_State * L)
{
const BitmapBuffer * b = checkBitmap(L, 1);
unsigned int w = luaL_checkunsigned(L, 2);
unsigned int h = luaL_checkunsigned(L, 3);
if (!b) {
lua_pushnil(L);
return 1;
}
BitmapBuffer **n = (BitmapBuffer**)lua_newuserdata(L, sizeof(BitmapBuffer*));
if (luaExtraMemoryUsage > LUA_MEM_EXTRA_MAX) {
// already allocated more than max allowed, fail
TRACE("luaOpenBitmap: Error, using too much memory %u/%u",
luaExtraMemoryUsage, LUA_MEM_EXTRA_MAX);
*n = 0;
} else {
*n = new BitmapBuffer(BMP_ARGB4444, w, h);
(*n)->clear();
(*n)->drawScaledBitmap(b, 0, 0, w, h);
}
if (*n) {
uint32_t size = (*n)->getDataSize();
luaExtraMemoryUsage += size;
TRACE("luaResizeBitmap: %p (%u)", *n, size);
}
luaL_getmetatable(L, LUA_BITMAPHANDLE);
lua_setmetatable(L, -2);
return 1;
}
/*luadoc
@function Bitmap.toMask(bitmap)
Return a 8bit bitmap mask that can be used with lcd.drawBitmapPattern()
@param bitmap (pointer) point to a bitmap previously opened with Bitmap.open()
@retval a bitmap mask
@notice Only available on Horus
@status current Introduced in 2.8.0
*/
static int luaBitmapTo8bitMask(lua_State * L)
{
const BitmapBuffer * b = checkBitmap(L, 1);
if (b) {
size_t size;
auto mask = b->to8bitMask(&size);
lua_pushlstring(L, (char*)mask, size);
}
else {
lua_pushlstring(L, "\x00\x00\x00\x00", 4);
}
return 1;
}
static int luaDestroyBitmap(lua_State * L)
{
BitmapBuffer * b = checkBitmap(L, 1);
@@ -608,6 +686,8 @@ static int luaDestroyBitmap(lua_State * L)
const luaL_Reg bitmapFuncs[] = {
{ "open", luaOpenBitmap },
{ "getSize", luaGetBitmapSize },
{ "resize", luaBitmapResize },
{ "toMask", luaBitmapTo8bitMask },
{ "__gc", luaDestroyBitmap },
{ NULL, NULL }
};
@@ -659,6 +739,79 @@ static int luaLcdDrawBitmap(lua_State *L)
return 0;
}
/*luadoc
@function lcd.drawBitmapPattern(bitmap, x, y [, flags])
Displays a bitmap pattern at (x,y)
@param bitmap (pointer) point to a bitmap previously opened with Bitmap.open()
@param x,y (positive numbers) starting coordinates
@param flags (optional) please see [Lcd functions overview](../lcd-functions-less-than-greater-than-luadoc-begin-lcd/lcd_functions-overview.html)
@notice Only available on Horus
@status current Introduced in 2.8.0
*/
static int luaLcdDrawBitmapPattern(lua_State *L)
{
if (!luaLcdAllowed || !luaLcdBuffer)
return 0;
const char* m = luaL_checkstring(L, 1);
if (m) {
auto x = luaL_checkunsigned(L, 2);
auto y = luaL_checkunsigned(L, 3);
auto flags = luaL_optunsigned(L, 4, 0);
flags = flagsRGB(flags);
luaLcdBuffer->drawBitmapPattern(x, y, reinterpret_cast<const uint8_t*>(m), flags);
}
return 0;
}
/*luadoc
@function lcd.drawBitmapPatternPie(bitmap, x, y, startAngle, endAngle [, flags])
Displays a bitmap pattern pie at (x,y)
@param bitmap (pointer) point to a bitmap previously opened with Bitmap.open()
@param x,y (positive numbers) starting coordinates
@param startAngle Start angle
@param endAngle End angle
@param flags (optional) please see [Lcd functions overview](../lcd-functions-less-than-greater-than-luadoc-begin-lcd/lcd_functions-overview.html)
@notice Only available on Horus
@status current Introduced in 2.8.0
*/
static int luaLcdDrawBitmapPatternPie(lua_State *L)
{
if (!luaLcdAllowed || !luaLcdBuffer)
return 0;
const char* m = luaL_checkstring(L, 1);
if (m) {
auto x = luaL_checkunsigned(L, 2);
auto y = luaL_checkunsigned(L, 3);
auto startAngle = luaL_checkinteger(L, 4);
auto endAngle = luaL_checkinteger(L, 5);
auto flags = luaL_optunsigned(L, 6, 0);
flags = flagsRGB(flags);
luaLcdBuffer->drawBitmapPatternPie(x, y, reinterpret_cast<const uint8_t*>(m), flags, startAngle, endAngle);
}
return 0;
}
/*luadoc
@function lcd.drawRectangle(x, y, w, h [, flags [, t [, opacity]]])
@@ -734,6 +887,39 @@ static int luaLcdDrawFilledRectangle(lua_State *L)
}
/*luadoc
@function lcd.invertRect(x, y, w, h [, flags])
Invert a rectangle zone from top left corner (x,y) of specified width and height
@param x,y (positive numbers) top left corner position
@param w (number) width in pixels
@param h (number) height in pixels
@param flags (optional) please see [Lcd functions overview](../lcd-functions-less-than-greater-than-luadoc-begin-lcd/lcd_functions-overview.html)
@status current Introduced in 2.8.0
*/
static int luaLcdInvertRect(lua_State *L)
{
if (!luaLcdAllowed || !luaLcdBuffer)
return 0;
int x = luaL_checkinteger(L, 1);
int y = luaL_checkinteger(L, 2);
int w = luaL_checkinteger(L, 3);
int h = luaL_checkinteger(L, 4);
LcdFlags flags = luaL_optunsigned(L, 5, 0);
flags = flagsRGB(flags);
luaLcdBuffer->invertRect(x, y, w, h, flags);
return 0;
}
/*luadoc
@function lcd.drawGauge(x, y, w, h, fill, maxfill [, flags])
@@ -1249,6 +1435,7 @@ const luaL_Reg lcdLib[] = {
{ "drawLine", luaLcdDrawLine },
{ "drawRectangle", luaLcdDrawRectangle },
{ "drawFilledRectangle", luaLcdDrawFilledRectangle },
{ "invertRect", luaLcdInvertRect },
{ "drawText", luaLcdDrawText },
{ "drawTextLines", luaLcdDrawTextLines },
{ "sizeText", luaLcdSizeText },
@@ -1259,6 +1446,8 @@ const luaL_Reg lcdLib[] = {
{ "drawSource", luaLcdDrawSource },
{ "drawGauge", luaLcdDrawGauge },
{ "drawBitmap", luaLcdDrawBitmap },
{ "drawBitmapPattern", luaLcdDrawBitmapPattern },
{ "drawBitmapPatternPie", luaLcdDrawBitmapPatternPie },
{ "setColor", luaLcdSetColor },
{ "getColor", luaLcdGetColor },
{ "RGB", luaRGB },
+28
View File
@@ -2447,6 +2447,27 @@ static int luaSources(lua_State * L)
return 3;
}
/*luadoc
@function getOutputValue(outputIndex)
@param outputIndex: integer identifying the output channel number 0 for CH1, up to MAX_OUTPUT_CHANNELS - 1.
@retval value current output value (number). Zero is returned for:
* non-existing outputs
@status current Introduced in 2.8.0
*/
static int luaGetOutputValue(lua_State * L)
{
mixsrc_t idx = luaL_checkinteger(L, 1);
if (idx >= 0 && idx < MAX_OUTPUT_CHANNELS) {
lua_pushinteger(L, channelOutputs[idx]);
} else {
lua_pushinteger(L, 0);
}
return 1;
}
const luaL_Reg opentxLib[] = {
{ "getTime", luaGetTime },
{ "getDateTime", luaGetDateTime },
@@ -2459,6 +2480,7 @@ const luaL_Reg opentxLib[] = {
{ "getRotEncSpeed", luaGetRotEncSpeed },
{ "getRotEncMode", luaGetRotEncMode },
{ "getValue", luaGetValue },
{ "getOutputValue", luaGetOutputValue },
{ "getRAS", luaGetRAS },
{ "getTxGPS", luaGetTxGPS },
{ "getFieldInfo", luaGetFieldInfo },
@@ -2581,6 +2603,10 @@ const luaR_value_entry opentxConstants[] = {
{ "SWITCH_COUNT", SWSRC_COUNT },
{ "MAX_SENSORS", MAX_TELEMETRY_SENSORS },
{ "MAX_OUTPUT_CHANNELS", MAX_OUTPUT_CHANNELS },
{ "LIMIT_EXT_PERCENT", LIMIT_EXT_PERCENT },
{ "LIMIT_STD_PERCENT", LIMIT_STD_PERCENT },
{ "LS_FUNC_NONE", LS_FUNC_NONE },
{ "LS_FUNC_VEQUAL", LS_FUNC_VEQUAL },
{ "LS_FUNC_VALMOSTEQUAL", LS_FUNC_VALMOSTEQUAL },
@@ -2631,6 +2657,8 @@ const luaR_value_entry opentxConstants[] = {
{ "COLOR", ZoneOption::Color },
{ "BOOL", ZoneOption::Bool },
{ "STRING", ZoneOption::String },
{ "TIMER", ZoneOption::Timer },
{ "TEXT_SIZE", ZoneOption::TextSize },
{ "MENU_HEADER_HEIGHT", COLOR2FLAGS(MENU_HEADER_HEIGHT) },
// Colors gui/colorlcd/colors.h
+110 -6
View File
@@ -38,22 +38,28 @@ Get current Model information
@retval table model information:
* `name` (string) model name
* `extendedLimits` (boolean) extended limits enabled
* `jitterFilter` (number) model level ADC filter
* `bitmap` (string) bitmap name (not present on X7)
* `filename` (string) model filename
@status current Introduced in 2.0.6, changed in 2.2.0, filename added in 2.6.0
@status current Introduced in 2.0.6, changed in 2.2.0, filename added in 2.6.0, extendedLimits, jitterFilter, and labels added in 2.8.0
*/
static int luaModelGetInfo(lua_State *L)
{
lua_newtable(L);
lua_pushtablenstring(L, "name", g_model.header.name);
lua_pushtableboolean(L, "extendedLimits", g_model.extendedLimits);
lua_pushtableinteger(L, "jitterFilter", g_model.jitterFilter);
#if LCD_DEPTH > 1
lua_pushtablenstring(L, "bitmap", g_model.header.bitmap);
#endif
#if defined(STORAGE_MODELSLIST)
lua_pushtablenstring(L, "labels", g_model.header.labels);
lua_pushtablenstring(L, "filename", g_eeGeneral.currModelFilename);
#else
lua_pushtablenstring(L, "labels", "");
char fname[MODELIDX_STRLEN + sizeof(YAML_EXT)];
getModelNumberStr(g_eeGeneral.currModel, fname);
strcat(fname, YAML_EXT);
@@ -73,7 +79,7 @@ Set the current Model information
@notice If a parameter is missing from the value, then
that parameter remains unchanged.
@status current Introduced in 2.0.6, changed in TODO
@status current Introduced in 2.0.6, extendedLimits and jitterFilter added in 2.8.0
*/
static int luaModelSetInfo(lua_State *L)
{
@@ -88,6 +94,14 @@ static int luaModelSetInfo(lua_State *L)
memcpy(modelHeaders[g_eeGeneral.currModel].name, g_model.header.name, sizeof(g_model.header.name));
#endif
}
else if (!strcmp(key, "extendedLimits")) {
g_model.extendedLimits = lua_toboolean(L, -1);
}
else if (!strcmp(key, "jitterFilter")) {
auto j = lua_tounsigned(L, -1);
if (j > OVERRIDE_ON) j = OVERRIDE_ON;
g_model.jitterFilter = j;
}
#if LCD_DEPTH > 1
else if (!strcmp(key, "bitmap")) {
const char * name = luaL_checkstring(L, -1);
@@ -260,8 +274,9 @@ Get model timer parameters
* `minuteBeep` (boolean) minute beep
* `persistent` (number) persistent timer
* `name` (string) timer name
* `showElapsed` (boolean) show elapsed
@status current Introduced in 2.0.0, name added in 2.3.6
@status current Introduced in 2.0.0, name added in 2.3.6, showElapsed added in 2.8.0
*/
static int luaModelGetTimer(lua_State *L)
{
@@ -276,6 +291,7 @@ static int luaModelGetTimer(lua_State *L)
lua_pushtableboolean(L, "minuteBeep", timer.minuteBeep);
lua_pushtableinteger(L, "persistent", timer.persistent);
lua_pushtablenstring(L, "name", timer.name);
lua_pushtableboolean(L, "showElapsed", timer.showElapsed);
}
else {
lua_pushnil(L);
@@ -295,7 +311,7 @@ Set model timer parameters
@notice If a parameter is missing from the value, then
that parameter remains unchanged.
@status current Introduced in 2.0.0, name added in 2.3.6
@status current Introduced in 2.0.0, name added in 2.3.6, showElapsed added in 2.8.0
*/
static int luaModelSetTimer(lua_State *L)
{
@@ -325,10 +341,13 @@ static int luaModelSetTimer(lua_State *L)
else if (!strcmp(key, "persistent")) {
timer.persistent = luaL_checkinteger(L, -1);
}
if (!strcmp(key, "name")) {
else if (!strcmp(key, "name")) {
const char * name = luaL_checkstring(L, -1);
strncpy(timer.name, name, sizeof(timer.name));
}
else if (!strcmp(key, "showElapsed")) {
timer.showElapsed = lua_toboolean(L, -1);
}
}
storageDirty(EE_MODEL);
}
@@ -1616,6 +1635,87 @@ static int luaModelResetSensor(lua_State *L)
return 1;
}
#if defined(HELI)
/*luadoc
@function model.getSwashRing()
Get heli swash parameters
@retval table with heli swash parameters:
* `type` (number) 0=---, 1=120, 2=120X, 3=140, 4=90
* `value` (number) swash ring value (normally 0)
* 'collectiveSource' (number) source index
* 'aileronSource' (number) source index
* 'elevatorSource' (number) source index
* 'collectiveWeight'(value) -100 to 100
* 'aileronWeight' (value) -100 to 100
* 'elevatorWeight' (value) -100 to 100
@status current Introduced in 2.8.0
*/
static int luaModelGetSwashRing(lua_State *L)
{
lua_newtable(L);
lua_pushtableinteger(L, "type", g_model.swashR.type);
lua_pushtableinteger(L, "value", g_model.swashR.value);
lua_pushtableinteger(L, "collectiveSource", g_model.swashR.collectiveSource);
lua_pushtableinteger(L, "aileronSource", g_model.swashR.aileronSource);
lua_pushtableinteger(L, "elevatorSource", g_model.swashR.elevatorSource);
lua_pushtableinteger(L, "collectiveWeight", g_model.swashR.collectiveWeight);
lua_pushtableinteger(L, "aileronWeight", g_model.swashR.aileronWeight);
lua_pushtableinteger(L, "elevatorWeight", g_model.swashR.elevatorWeight);
return 1;
}
/*luadoc
@function model.setSwashRing(params)
Set heli swash parameters
@param value (table) swash ring parameters, see model.getSwashRing() for table format
@notice If a parameter is missing, then that parameter remains unchanged.
@status current Introduced in 2.8.0
*/
static int luaModelSetSwashRing(lua_State *L)
{
luaL_checktype(L, -1, LUA_TTABLE);
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
luaL_checktype(L, -2, LUA_TSTRING); // key is string
const char * key = luaL_checkstring(L, -2);
if (!strcmp(key, "type")) {
g_model.swashR.type = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "value")) {
g_model.swashR.value = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "collectiveSource")) {
g_model.swashR.collectiveSource = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "aileronSource")) {
g_model.swashR.aileronSource = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "elevatorSource")) {
g_model.swashR.elevatorSource = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "collectiveWeight")) {
g_model.swashR.collectiveWeight = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "aileronWeight")) {
g_model.swashR.aileronWeight = luaL_checkinteger(L, -1);
}
else if (!strcmp(key, "elevatorWeight")) {
g_model.swashR.elevatorWeight = luaL_checkinteger(L, -1);
}
}
storageDirty(EE_MODEL);
return 0;
}
#endif // HELI
const luaL_Reg modelLib[] = {
{ "getInfo", luaModelGetInfo },
{ "setInfo", luaModelSetInfo },
@@ -1652,5 +1752,9 @@ const luaL_Reg modelLib[] = {
#endif
{ "getSensor", luaModelGetSensor },
{ "resetSensor", luaModelResetSensor },
{ NULL, NULL } /* sentinel */
#if defined(HELI)
{ "getSwashRing", luaModelGetSwashRing },
{ "setSwashRing", luaModelSetSwashRing },
#endif
{ nullptr, nullptr } /* sentinel */
};