diff --git a/app/modules/u8g.c b/app/modules/u8g.c index 9f85f7ee..08998f06 100644 --- a/app/modules/u8g.c +++ b/app/modules/u8g.c @@ -28,18 +28,22 @@ const static u8g_fntpgm_uint8_t *font_array[] = }; +static lu8g_userdata_t *get_lud( lua_State *L ) +{ + lu8g_userdata_t *lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display"); + luaL_argcheck(L, lud, 1, "u8g.display expected"); + return lud; +} + + // Lua: u8g.setFont( self, font ) static int lu8g_setFont( lua_State *L ) { lu8g_userdata_t *lud; - uint8_t stack = 1; - lud = (lu8g_userdata_t *)luaL_checkudata(L, stack, "u8g.display"); - luaL_argcheck(L, lud, stack, "u8g.display expected"); - stack++; - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; + uint8_t stack = 2; unsigned fontnr = luaL_checkinteger( L, stack ); stack++; @@ -54,10 +58,7 @@ static int lu8g_setFontRefHeightExtendedText( lua_State *L ) { lu8g_userdata_t *lud; - lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display"); - luaL_argcheck(L, lud, 1, "u8g.display expected"); - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; u8g_SetFontRefHeightExtendedText( &(lud->u8g) ); @@ -70,10 +71,7 @@ static int lu8g_setDefaultForegroundColor( lua_State *L ) { lu8g_userdata_t *lud; - lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display"); - luaL_argcheck(L, lud, 1, "u8g.display expected"); - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; u8g_SetDefaultForegroundColor( &(lud->u8g) ); @@ -86,10 +84,7 @@ static int lu8g_setFontPosTop( lua_State *L ) { lu8g_userdata_t *lud; - lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display"); - luaL_argcheck(L, lud, 1, "u8g.display expected"); - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; u8g_SetFontPosTop( &(lud->u8g) ); @@ -97,18 +92,13 @@ static int lu8g_setFontPosTop( lua_State *L ) return 0; } -// Lua: pix_len = u8g.drawStr( self, x, y, string ) -static int lu8g_drawStr( lua_State *L ) +static int lu8g_generic_drawStr( lua_State *L, uint8_t rot ) { lu8g_userdata_t *lud; - uint8_t stack = 1; - lud = (lu8g_userdata_t *)luaL_checkudata(L, stack, "u8g.display"); - luaL_argcheck(L, lud, stack, "u8g.display expected"); - stack++; - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; + uint8_t stack = 2; u8g_uint_t x = luaL_checkinteger( L, stack ); stack++; @@ -121,23 +111,124 @@ static int lu8g_drawStr( lua_State *L ) if (s == NULL) return 0; - lua_pushinteger( L, u8g_DrawStr( &(lud->u8g), x, y, s ) ); + switch (rot) + { + case 1: + lua_pushinteger( L, u8g_DrawStr90( &(lud->u8g), x, y, s ) ); + break; + case 2: + lua_pushinteger( L, u8g_DrawStr180( &(lud->u8g), x, y, s ) ); + break; + case 3: + lua_pushinteger( L, u8g_DrawStr270( &(lud->u8g), x, y, s ) ); + break; + default: + lua_pushinteger( L, u8g_DrawStr( &(lud->u8g), x, y, s ) ); + break; + } return 1; } + +// Lua: pix_len = u8g.drawStr( self, x, y, string ) +static int lu8g_drawStr( lua_State *L ) +{ + lu8g_userdata_t *lud; + + return lu8g_generic_drawStr( L, 0 ); +} + +// Lua: pix_len = u8g.drawStr90( self, x, y, string ) +static int lu8g_drawStr90( lua_State *L ) +{ + lu8g_userdata_t *lud; + + return lu8g_generic_drawStr( L, 1 ); +} + +// Lua: pix_len = u8g.drawStr180( self, x, y, string ) +static int lu8g_drawStr180( lua_State *L ) +{ + lu8g_userdata_t *lud; + + return lu8g_generic_drawStr( L, 2 ); +} + +// Lua: pix_len = u8g.drawStr270( self, x, y, string ) +static int lu8g_drawStr270( lua_State *L ) +{ + lu8g_userdata_t *lud; + + return lu8g_generic_drawStr( L, 3 ); +} + +// Lua: u8g.drawLine( self, x1, y1, x2, y2 ) +static int lu8g_drawLine( lua_State *L ) +{ + lu8g_userdata_t *lud; + + if ((lud = get_lud( L )) == NULL) + return 0; + uint8_t stack = 2; + + u8g_uint_t x1 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y1 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t x2 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y2 = luaL_checkinteger( L, stack ); + stack++; + + u8g_DrawLine( &(lud->u8g), x1, y1, x2, y2 ); + + return 0; +} + +// Lua: u8g.drawTriangle( self, x0, y0, x1, y1, x2, y2 ) +static int lu8g_drawTriangle( lua_State *L ) +{ + lu8g_userdata_t *lud; + + if ((lud = get_lud( L )) == NULL) + return 0; + uint8_t stack = 2; + + u8g_uint_t x0 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y0 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t x1 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y1 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t x2 = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y2 = luaL_checkinteger( L, stack ); + stack++; + + u8g_DrawTriangle( &(lud->u8g), x0, y0, x1, y1, x2, y2 ); + + return 0; +} + // Lua: u8g.drawBox( self, x, y, width, height ) static int lu8g_drawBox( lua_State *L ) { lu8g_userdata_t *lud; - uint8_t stack = 1; - lud = (lu8g_userdata_t *)luaL_checkudata(L, stack, "u8g.display"); - luaL_argcheck(L, lud, stack, "u8g.display expected"); - stack++; - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; + uint8_t stack = 2; u8g_uint_t x = luaL_checkinteger( L, stack ); stack++; @@ -156,18 +247,43 @@ static int lu8g_drawBox( lua_State *L ) return 0; } +// Lua: u8g.drawRBox( self, x, y, width, height, radius ) +static int lu8g_drawRBox( lua_State *L ) +{ + lu8g_userdata_t *lud; + + if ((lud = get_lud( L )) == NULL) + return 0; + uint8_t stack = 2; + + u8g_uint_t x = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t w = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t h = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t r = luaL_checkinteger( L, stack ); + stack++; + + u8g_DrawRBox( &(lud->u8g), x, y, w, h, r ); + + return 0; +} + // Lua: u8g.drawFrame( self, x, y, width, height ) static int lu8g_drawFrame( lua_State *L ) { lu8g_userdata_t *lud; - uint8_t stack = 1; - lud = (lu8g_userdata_t *)luaL_checkudata(L, stack, "u8g.display"); - luaL_argcheck(L, lud, stack, "u8g.display expected"); - stack++; - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; + uint8_t stack = 2; u8g_uint_t x = luaL_checkinteger( L, stack ); stack++; @@ -186,18 +302,46 @@ static int lu8g_drawFrame( lua_State *L ) return 0; } +// Lua: u8g.drawRFrame( self, x, y, width, height, radius ) +static int lu8g_drawRFrame( lua_State *L ) +{ + lu8g_userdata_t *lud; + + if ((lud = get_lud( L )) == NULL) + return 0; + uint8_t stack = 2; + + if (lud == NULL) + return 0; + + u8g_uint_t x = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t y = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t w = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t h = luaL_checkinteger( L, stack ); + stack++; + + u8g_uint_t r = luaL_checkinteger( L, stack ); + stack++; + + u8g_DrawRFrame( &(lud->u8g), x, y, w, h, r ); + + return 0; +} + // Lua: u8g.drawDisc( self, x0, y0, rad, opt = U8G_DRAW_ALL ) static int lu8g_drawDisc( lua_State *L ) { lu8g_userdata_t *lud; - uint8_t stack = 1; - lud = (lu8g_userdata_t *)luaL_checkudata(L, stack, "u8g.display"); - luaL_argcheck(L, lud, stack, "u8g.display expected"); - stack++; - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; + uint8_t stack = 2; u8g_uint_t x0 = luaL_checkinteger( L, stack ); stack++; @@ -220,14 +364,10 @@ static int lu8g_drawDisc( lua_State *L ) static int lu8g_drawCircle( lua_State *L ) { lu8g_userdata_t *lud; - uint8_t stack = 1; - lud = (lu8g_userdata_t *)luaL_checkudata(L, stack, "u8g.display"); - luaL_argcheck(L, lud, stack, "u8g.display expected"); - stack++; - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; + uint8_t stack = 2; u8g_uint_t x0 = luaL_checkinteger( L, stack ); stack++; @@ -251,10 +391,7 @@ static int lu8g_firstPage( lua_State *L ) { lu8g_userdata_t *lud; - lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display"); - luaL_argcheck(L, lud, 1, "u8g.display expected"); - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; u8g_FirstPage( &(lud->u8g) ); @@ -267,10 +404,7 @@ static int lu8g_nextPage( lua_State *L ) { lu8g_userdata_t *lud; - lud = (lu8g_userdata_t *)luaL_checkudata(L, 1, "u8g.display"); - luaL_argcheck(L, lud, 1, "u8g.display expected"); - - if (lud == NULL) + if ((lud = get_lud( L )) == NULL) return 0; lua_pushboolean( L, u8g_NextPage( &(lud->u8g) ) ); @@ -449,8 +583,15 @@ static const LUA_REG_TYPE lu8g_display_map[] = { LSTRKEY( "setDefaultForegroundColor" ), LFUNCVAL( lu8g_setDefaultForegroundColor ) }, { LSTRKEY( "setFontPosTop" ), LFUNCVAL( lu8g_setFontPosTop ) }, { LSTRKEY( "drawStr" ), LFUNCVAL( lu8g_drawStr ) }, + { LSTRKEY( "drawStr90" ), LFUNCVAL( lu8g_drawStr90 ) }, + { LSTRKEY( "drawStr180" ), LFUNCVAL( lu8g_drawStr180 ) }, + { LSTRKEY( "drawStr270" ), LFUNCVAL( lu8g_drawStr270 ) }, { LSTRKEY( "drawBox" ), LFUNCVAL( lu8g_drawBox ) }, + { LSTRKEY( "drawLine" ), LFUNCVAL( lu8g_drawLine ) }, + { LSTRKEY( "drawTriangle" ), LFUNCVAL( lu8g_drawTriangle ) }, + { LSTRKEY( "drawRBox" ), LFUNCVAL( lu8g_drawRBox ) }, { LSTRKEY( "drawFrame" ), LFUNCVAL( lu8g_drawFrame ) }, + { LSTRKEY( "drawRFrame" ), LFUNCVAL( lu8g_drawRFrame ) }, { LSTRKEY( "drawDisc" ), LFUNCVAL( lu8g_drawDisc ) }, { LSTRKEY( "drawCircle" ), LFUNCVAL( lu8g_drawCircle ) }, { LSTRKEY( "firstPage" ), LFUNCVAL( lu8g_firstPage ) }, diff --git a/lua_examples/graphics_test.lua b/lua_examples/graphics_test.lua new file mode 100644 index 00000000..5885fa08 --- /dev/null +++ b/lua_examples/graphics_test.lua @@ -0,0 +1,136 @@ + +-- setup I2c and connect display +function init_i2c_display() + sda = 5 + scl = 6 + sla = 0x3c + i2c.setup(0, sda, scl, i2c.SLOW) + disp = u8g.ssd1306_128x64_i2c(sla) +end + + +-- graphic test components +function prepare() + disp:setFont(u8g.font_6x10) + disp:setFontRefHeightExtendedText() + disp:setDefaultForegroundColor() + disp:setFontPosTop() +end + +function box_frame(a) + disp:drawStr(0, 0, "drawBox") + disp:drawBox(5, 10, 20, 10) + disp:drawBox(10+a, 15, 30, 7) + disp:drawStr(0, 30, "drawFrame") + disp:drawFrame(5, 10+30, 20, 10) + disp:drawFrame(10+a, 15+30, 30, 7) +end + +function disc_circle(a) + disp:drawStr(0, 0, "drawDisc") + disp:drawDisc(10, 18, 9) + disp:drawDisc(24+a, 16, 7) + disp:drawStr(0, 30, "drawCircle") + disp:drawCircle(10, 18+30, 9) + disp:drawCircle(24+a, 16+30, 7) +end + +function r_frame(a) + disp:drawStr(0, 0, "drawRFrame/Box") + disp:drawRFrame(5, 10, 40, 30, a+1) + disp:drawRBox(50, 10, 25, 40, a+1) +end + +function stringtest(a) + disp:drawStr(30+a, 31, " 0") + disp:drawStr90(30, 31+a, " 90") + disp:drawStr180(30-a, 31, " 180") + disp:drawStr270(30, 31-a, " 270") +end + +function line(a) + disp:drawStr(0, 0, "drawLine") + disp:drawLine(7+a, 10, 40, 55) + disp:drawLine(7+a*2, 10, 60, 55) + disp:drawLine(7+a*3, 10, 80, 55) + disp:drawLine(7+a*4, 10, 100, 55) +end + +function triangle(a) + local offset = a + disp:drawStr(0, 0, "drawTriangle") + disp:drawTriangle(14,7, 45,30, 10,40) + disp:drawTriangle(14+offset,7-offset, 45+offset,30-offset, 57+offset,10-offset) + disp:drawTriangle(57+offset*2,10, 45+offset*2,30, 86+offset*2,53) + disp:drawTriangle(10+offset,40+offset, 45+offset,30+offset, 86+offset,53+offset) +end + +function ascii_1() + local x, y, s + disp:drawStr(0, 0, "ASCII page 1") + for y = 0, 5, 1 do + for x = 0, 15, 1 do + s = y*16 + x + 32 + disp:drawStr(x*7, y*10+10, string.char(s)) + end + end +end + +function ascii_2() + local x, y, s + disp:drawStr(0, 0, "ASCII page 2") + for y = 0, 5, 1 do + for x = 0, 15, 1 do + s = y*16 + x + 160 + disp:drawStr(x*7, y*10+10, string.char(s)) + end + end +end + + +-- the draw() routine +function draw(draw_state) + local component = bit.rshift(draw_state, 3) + + prepare() + + if (component == 0) then + box_frame(bit.band(draw_state, 7)) + elseif (component == 1) then + disc_circle(bit.band(draw_state, 7)) + elseif (component == 2) then + r_frame(bit.band(draw_state, 7)) + elseif (component == 3) then + stringtest(bit.band(draw_state, 7)) + elseif (component == 4) then + line(bit.band(draw_state, 7)) + elseif (component == 5) then + triangle(bit.band(draw_state, 7)) + elseif (component == 6) then + ascii_1() + elseif (component == 7) then + ascii_2() + end +end + +function graphics_test() + init_i2c_display() + + print("--- Starting Graphics Test ---") + + -- cycle through all components + local draw_state + for draw_state = 0, 7 + 7*8, 1 do + disp:firstPage() + repeat + draw(draw_state) + until disp:nextPage() == false + --print(node.heap()) + -- re-trigger Watchdog! + tmr.wdclr() + end + + print("--- Graphics Test done ---") +end + +graphics_test()