/* * 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 #include #include "opentx.h" #include "lua/lua_api.h" /*luadoc @function lcd.refresh() Refresh the LCD screen @status current Introduced in 2.2.0 @notice This function only works in stand-alone and telemetry scripts. */ static int luaLcdRefresh(lua_State *L) { if (luaLcdAllowed) lcdRefresh(); return 0; } /*luadoc @function lcd.clear() Clear the LCD screen @status current Introduced in 2.0.0 @notice This function only works in stand-alone and telemetry scripts. */ static int luaLcdClear(lua_State *L) { if (luaLcdAllowed) lcdClear(); return 0; } /*luadoc @function lcd.drawPoint(x, y) Draw a single pixel at (x,y) position @param x (positive number) x position @param y (positive number) y position @notice Taranis has an LCD display width of 212 pixels and height of 64 pixels. Position (0,0) is at top left. Y axis is negative, top line is 0, bottom line is 63. Drawing on an existing black pixel produces white pixel (TODO check this!) @status current Introduced in 2.0.0 */ static int luaLcdDrawPoint(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); lcdDrawPoint(x, y); return 0; } /*luadoc @function lcd.drawLine(x1, y1, x2, y2, pattern, flags) Draw a straight line on LCD @param x1,y1 (positive numbers) starting coordinate @param x2,y2 (positive numbers) end coordinate @param pattern TODO @param flags TODO @notice If the start or the end of the line is outside the LCD dimensions, then the whole line will not be drawn (starting from OpenTX 2.1.5) @status current Introduced in 2.0.0 */ static int luaLcdDrawLine(lua_State *L) { if (!luaLcdAllowed) return 0; int x1 = luaL_checkinteger(L, 1); int y1 = luaL_checkinteger(L, 2); int x2 = luaL_checkinteger(L, 3); int y2 = luaL_checkinteger(L, 4); int pat = luaL_checkinteger(L, 5); int flags = luaL_checkinteger(L, 6); if (pat == SOLID) { if (x1 == x2) { lcdDrawSolidVerticalLine(x1, y2 >= y1 ? y1 : y1+1, y2 >= y1 ? y2-y1+1 : y2-y1-1, flags); return 0; } else if (y1 == y2) { lcdDrawSolidHorizontalLine(x2 >= x1 ? x1 : x1+1, y1, x2 >= x1 ? x2-x1+1 : x2-x1-1, flags); return 0; } } lcdDrawLine(x1, y1, x2, y2, pat, flags); return 0; } #if !defined(COLORLCD) /*luadoc @function lcd.getLastPos() Returns the last x position from previous output @retval number (integer) x position @status current Introduced in 2.0.0 */ static int luaLcdGetLastPos(lua_State *L) { lua_pushinteger(L, lcdLastPos); return 1; } #endif /*luadoc @function lcd.drawText(x, y, text [, flags]) Draw a text beginning at (x,y) @param x,y (positive numbers) starting coordinate @param text (string) text to display @param flags (unsigned number) drawing flags. All values can be combined together using the + character. ie BLINK + DBLSIZE. See the Appendix for available characters in each font set. * `0 or not specified` normal font * `XXLSIZE` jumbo sized font * `DBLSIZE` double size font * `MIDSIZE` mid sized font * `SMLSIZE` small font * `INVERS` inverted display * `BLINK` blinking text @status current Introduced in 2.0.0 */ static int luaLcdDrawText(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); const char * s = luaL_checkstring(L, 3); unsigned int att = luaL_optunsigned(L, 4, 0); lcdDrawText(x, y, s, att); return 0; } /*luadoc @function lcd.drawTimer(x, y, value [, flags]) Display a value formatted as time at (x,y) @param x,y (positive numbers) starting coordinate @param value (number) time in seconds @param flags (unsigned number) drawing flags: * `0 or not specified` normal representation (minutes and seconds) * `TIMEHOUR` display hours * other general LCD flag also apply @status current Introduced in 2.0.0 */ static int luaLcdDrawTimer(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int seconds = luaL_checkinteger(L, 3); unsigned int att = luaL_optunsigned(L, 4, 0); #if defined(COLORLCD) putsTimer(x, y, seconds, att|LEFT); #else putsTimer(x, y, seconds, att|LEFT, att); #endif return 0; } /*luadoc @function lcd.drawNumber(x, y, value [, flags]) Display a number at (x,y) @param x,y (positive numbers) starting coordinate @param value (number) value to display @param flags (unsigned number) drawing flags: * `0 or not specified` normal representation * `PREC1` display with one decimal place (number 386 is displayed as 38.6) * `PREC2` display with tow decimal places (number 386 is displayed as 3.86) * other general LCD flag also apply @status current Introduced in 2.0.0 */ static int luaLcdDrawNumber(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int val = luaL_checkinteger(L, 3); unsigned int att = luaL_optunsigned(L, 4, 0); lcdDrawNumber(x, y, val, att); return 0; } /*luadoc @function lcd.drawChannel(x, y, source, flags) Display a telemetry value at (x,y) @param x,y (positive numbers) starting coordinate @param source can be a source identifier (number) or a source name (string). See getValue() @param flags (unsigned number) drawing flags @status current Introduced in 2.0.6, changed in 2.1.0 (only telemetry sources are valid) */ static int luaLcdDrawChannel(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int channel = -1; if (lua_isnumber(L, 3)) { channel = luaL_checkinteger(L, 3); } else { const char * what = luaL_checkstring(L, 3); LuaField field; bool found = luaFindFieldByName(what, field); if (found) { channel = field.id; } } unsigned int att = luaL_optunsigned(L, 4, 0); getvalue_t value = getValue(channel); putsTelemetryChannelValue(x, y, (channel-MIXSRC_FIRST_TELEM)/3, value, att); return 0; } /*luadoc @function lcd.drawSwitch(x, y, switch, flags) Draw a text representation of switch at (x,y) @param x,y (positive numbers) starting coordinate @param switch (number) number of switch to display, negative number displays negated switch @param flags (unsigned number) drawing flags, only SMLSIZE, BLINK and INVERS. @status current Introduced in 2.0.0 */ static int luaLcdDrawSwitch(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int s = luaL_checkinteger(L, 3); unsigned int att = luaL_optunsigned(L, 4, 0); putsSwitches(x, y, s, att); return 0; } /*luadoc @function lcd.drawSource(x, y, source [, flags]) Displays the name of the corresponding input as defined by the source at (x,y) @param x,y (positive numbers) starting coordinate @param source (number) source index @param flags (unsigned number) drawing flags @status current Introduced in 2.0.0 */ static int luaLcdDrawSource(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int s = luaL_checkinteger(L, 3); unsigned int att = luaL_optunsigned(L, 4, 0); putsMixerSource(x, y, s, att); return 0; } #if !defined(COLORLCD) /*luadoc @function lcd.drawPixmap(x, y, name) Draw a bitmap at (x,y) @param x,y (positive numbers) starting coordinate @param name (string) full path to the bitmap on SD card (i.e. “/BMP/test.bmp”) @notice Only available on monochrome screens @status current Introduced in 2.0.0 */ static int luaLcdDrawPixmap(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); const char * filename = luaL_checkstring(L, 3); #if defined(PCBTARANIS) uint8_t bitmap[BITMAP_BUFFER_SIZE(LCD_W/2, LCD_H)]; // width max is LCD_W/2 pixels for saving stack and avoid a malloc here if (lcdLoadBitmap(bitmap, filename, LCD_W/2, LCD_H)) { lcdDrawBitmap(x, y, bitmap); } #else uint8_t * bitmap = lcdLoadBitmap(filename); if (bitmap) { lcdDrawBitmap(x, y, bitmap); free(bitmap); } #endif return 0; } #endif /*luadoc @function lcd.drawRectangle(x, y, w, h [, flags]) Draw a rectangle 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 (unsigned number) drawing flags @status current Introduced in 2.0.0 */ static int luaLcdDrawRectangle(lua_State *L) { if (!luaLcdAllowed) 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); unsigned int flags = luaL_optunsigned(L, 5, 0); lcdDrawRect(x, y, w, h, 0xff, flags); return 0; } /*luadoc @function lcd.drawFilledRectangle(x, y, w, h [, flags]) Draw a solid rectangle 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 (unsigned number) drawing flags @status current Introduced in 2.0.0 */ static int luaLcdDrawFilledRectangle(lua_State *L) { if (!luaLcdAllowed) 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); unsigned int flags = luaL_optunsigned(L, 5, 0); lcdDrawFilledRect(x, y, w, h, SOLID, flags); return 0; } #if !defined(COLORLCD) /*luadoc @function lcd.drawGauge(x, y, w, h, fill, maxfill) Draw a simple gauge that is filled based upon fill value @param x,y (positive numbers) top left corner position @param w (number) width in pixels @param h (number) height in pixels @param fill (number) amount of fill to apply @param maxfill (number) total value of fill @param flags (unsigned number) drawing flags @status current Introduced in 2.0.0 */ static int luaLcdDrawGauge(lua_State *L) { if (!luaLcdAllowed) 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); int num = luaL_checkinteger(L, 5); int den = luaL_checkinteger(L, 6); // int flags = luaL_checkinteger(L, 7); lcdDrawRect(x, y, w, h); uint8_t len = limit((uint8_t)1, uint8_t(w*num/den), uint8_t(w)); lcdDrawSolidFilledRect(x+1, y+1, len, h-2); return 0; } #endif #if !defined(COLORLCD) /*luadoc @function lcd.drawScreenTitle(title, page, pages) Draw a title bar @param title (string) text for the title @param page (number) page number @param pages (number) total number of pages. Only used as indicator on the right side of title bar. (i.e. idx=2, cnt=5, display `2/5`) @notice Only available on monochrome screens @status current Introduced in 2.0.0 */ static int luaLcdDrawScreenTitle(lua_State *L) { if (!luaLcdAllowed) return 0; const char * str = luaL_checkstring(L, 1); int idx = luaL_checkinteger(L, 2); int cnt = luaL_checkinteger(L, 3); if (cnt) drawScreenIndex(idx-1, cnt, 0); lcdDrawFilledRect(0, 0, LCD_W, FH, SOLID, FILL_WHITE|GREY_DEFAULT); title(str); return 0; } #endif #if !defined(COLORLCD) /*luadoc @function lcd.drawCombobox(x, y, w, list, idx [, flags]) Draw a combo box @param x,y (positive numbers) top left corner position @param w (number) width of combo box in pixels @param list (table) combo box elements, each element is a string @param idx (integer) index of entry to highlight @param page (number) page number @param flags (unsigned number) drawing flags, the flags can not be combined: * `BLINK` combo box is expanded * `INVERS` combo box collapsed, text inversed * `0 or not present` combo box collapsed, text normal @status current Introduced in 2.0.0 */ static int luaLcdDrawCombobox(lua_State *L) { if (!luaLcdAllowed) return 0; int x = luaL_checkinteger(L, 1); int y = luaL_checkinteger(L, 2); int w = luaL_checkinteger(L, 3); luaL_checktype(L, 4, LUA_TTABLE); int count = luaL_len(L, 4); /* get size of table */ int idx = luaL_checkinteger(L, 5); unsigned int flags = luaL_optunsigned(L, 6, 0); if (idx >= count) { // TODO error } if (flags & BLINK) { lcdDrawFilledRect(x, y, w-9, count*9+2, SOLID, ERASE); lcdDrawRect(x, y, w-9, count*9+2); for (int i=0; i