From 677c279f48882a9fe204cff01c49aee3fa6bd2a0 Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Tue, 7 Nov 2017 18:30:51 -0500 Subject: [PATCH] Initial support for color palettes See examples of usage in draw-snake2 and draw-together. At present, there is no support in the touch module for this, only via the message parser. --- README.rst | 5 +++-- draw-butterfly.lua | 6 +++--- draw-candle.lua | 6 +++++- draw-devilish.lua | 4 ++-- draw-fill.lua | 2 +- draw-flower.lua | 7 +++++-- draw-happy.lua | 4 ++-- draw-heart.lua | 4 ++-- draw-heartbeat.lua | 4 ++-- draw-kiss.lua | 4 ++-- draw-laserchase.lua | 4 ++-- draw-nom.lua | 4 ++-- draw-oo.lua | 4 ++-- draw-shifty.lua | 4 ++-- draw-shifty2.lua | 4 ++-- draw-snake.lua | 4 ++-- draw-snake2.lua | 10 +++++++--- draw-staryeyes.lua | 9 ++++++--- draw-together.lua | 27 +++++++++++++++++++++------ draw-xx.lua | 4 ++-- init2.lua | 2 +- lamp-remote.lua | 24 +++++++++++++++++------- lamp-touch.lua | 2 +- 23 files changed, 94 insertions(+), 54 deletions(-) diff --git a/README.rst b/README.rst index 91f5490..6a3864c 100644 --- a/README.rst +++ b/README.rst @@ -117,8 +117,9 @@ expected to *return a function* which takes, in order, * a ws2812 framebuffer object into which all drawing should happen. This framebuffer should be closed over in any timer callbacks. -* a color parameter, expressed as three arguments 0-255: green, red, blue - (as per ws2812 byte ordering). +* A color palette array. Each entry is a string of three, where the bytes + form the green, red, and blue color values (0-255), as per ws2812 byte + ordering. Most drawings will simply use entry 1. ``lamp-touch.lua`` (see below) knows the naming scheme used by ``init2.lua`` and so walks the list of files on the system looking for files whose name diff --git a/draw-butterfly.lua b/draw-butterfly.lua index f28b8d6..b110094 100644 --- a/draw-butterfly.lua +++ b/draw-butterfly.lua @@ -1,6 +1,6 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) - local c = string.char(g,r,b) + local c = p[1] local ft = { [1] = function() fb:set(2,c) fb:set(9,0,0,0) fb:set(10,c) fb:set(17,0,0,0) fb:set(18,c) fb:set(14,c) fb:set(15,0,0,0) fb:set(22,c) fb:set(23,0,0,0) fb:set(26,c) end, --start flapping [2] = function() fb:set(2,0,0,0) fb:set(3,c) fb:set(6,0,0,0) fb:set(27,c) fb:set(5,c) @@ -27,4 +27,4 @@ return function(t,fb,g,r,b) ix = (ix == 4 and 1) or ix + 1 dodraw() end) - end \ No newline at end of file + end diff --git a/draw-candle.lua b/draw-candle.lua index 37eb65c..26fdecd 100644 --- a/draw-candle.lua +++ b/draw-candle.lua @@ -7,13 +7,17 @@ -- 24 o W W W W W W o -- -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) -- static base local i,v for i,v in ipairs({18,23,26,27,28,29,30,31}) do fb:set(v,2,2,1) end -- whiteish (W) for i,v in ipairs({10,15,19,20,21,22}) do fb:set(v,1,1,1) end -- dim white (w) + local g = p[1]:byte(1) + local r = p[1]:byte(2) + local b = p[1]:byte(3) + local cmax = math.max(r,g,b) -- off channels stay off, on channels stay on, just minimally dim diff --git a/draw-devilish.lua b/draw-devilish.lua index 77921a1..b156bd2 100644 --- a/draw-devilish.lua +++ b/draw-devilish.lua @@ -2,9 +2,9 @@ -- x o o x o o x o -- x o o o o x x o -- o x o o x o o x -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) - local c = string.char(g,r,b) + local c = p[1] fb:set( 2,c) fb:set( 5,c) fb:set( 8,c) fb:set( 9,c) fb:set(12,c) fb:set(15,c) fb:set(17,c) fb:set(22,c) fb:set(23,c) diff --git a/draw-fill.lua b/draw-fill.lua index 27eee30..3dd5d62 100644 --- a/draw-fill.lua +++ b/draw-fill.lua @@ -1 +1 @@ -return function(t,fb,g,r,b) fb:fill(g,r,b) end +return function(t,fb,p) fb:fill(p[1]:byte(1),p[1]:byte(2),p[1]:byte(3)) end diff --git a/draw-flower.lua b/draw-flower.lua index f0823fe..e9c65be 100644 --- a/draw-flower.lua +++ b/draw-flower.lua @@ -5,9 +5,12 @@ -- 24 o o l o f f f o -- -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) - local c = string.char(g,r,b) + local c = p[1] + local g = c:byte(1) + local r = c:byte(2) + local b = c:byte(3) local cdim = string.char(math.floor((g+1)/2),math.floor((r+1)/2),math.floor((b+1)/2)) for i,v in ipairs({17,18,19,20}) do fb:set(v,0xf,0,0) end -- stem (s) diff --git a/draw-happy.lua b/draw-happy.lua index 8e41787..963479d 100644 --- a/draw-happy.lua +++ b/draw-happy.lua @@ -5,8 +5,8 @@ -- 16 o o o o o o o o -- 24 o o o x x o o o -- -return function(t,fb,g,r,b) - local c = string.char(g,r,b) +return function(t,fb,p) + local c = p[1] local i,v fb:fill(0,0,0) for i,v in ipairs({2,7,9,11,14,16,28,29}) do fb:set(v,c) end diff --git a/draw-heart.lua b/draw-heart.lua index 39dd90e..c71183a 100644 --- a/draw-heart.lua +++ b/draw-heart.lua @@ -1,6 +1,6 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) - local c = string.char(g,r,b) + local c = p[1] fb:set( 3,c) fb:set( 5,c) fb:set(10,c) fb:set(11,c) fb:set(12,c) fb:set(13,c) fb:set(14,c) fb:set(19,c) fb:set(20,c) fb:set(21,c) diff --git a/draw-heartbeat.lua b/draw-heartbeat.lua index 218baaf..50a5098 100644 --- a/draw-heartbeat.lua +++ b/draw-heartbeat.lua @@ -1,5 +1,5 @@ -return function(t,fb,g,r,b) - local c = string.char(g,r,b) +return function(t,fb,p) + local c = p[1] local ft = { [1] = function() fb:set(11,c) fb:set(13,c) end, -- side chambers [2] = function() fb:set(11,0,0,0) fb:set(20,c) fb:set(13,0,0,0) end, -- bottom chamber [3] = function() fb:set(20,0,0,0) end, -- empty diff --git a/draw-kiss.lua b/draw-kiss.lua index 230df77..8cde5a5 100644 --- a/draw-kiss.lua +++ b/draw-kiss.lua @@ -2,10 +2,10 @@ -- 0 x 0 - - x - - -- 1 0 1 x x - - - -- - - - - - x - - -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) local ix = 1 - local c = string.char(g,r,b) + local c = p[1] fb:set( 2,c) fb:set( 9,c) fb:set(10,c) fb:set(11,c) fb:set(14,c) fb:set(18,c) fb:set(20,c) fb:set(21,c) fb:set(30,c) diff --git a/draw-laserchase.lua b/draw-laserchase.lua index 51e2805..3ae593f 100644 --- a/draw-laserchase.lua +++ b/draw-laserchase.lua @@ -1,6 +1,6 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) local ix = 1 - local c = string.char(g,r,b) + local c = p[1] fb:fill(0,0,0) t:register(50,tmr.ALARM_AUTO,function() fb:fade(2); fb:set(ix,c); dodraw() diff --git a/draw-nom.lua b/draw-nom.lua index 49c5a7b..17bc5e8 100644 --- a/draw-nom.lua +++ b/draw-nom.lua @@ -1,7 +1,7 @@ -- -return function(t,fb,g,r,b) +return function(t,fb,p) local ix = 2 -- since we start effectively in state 1... - local c = string.char(g,r,b) + local c = p[1] local z = string.char(0,0,0) local ft = { -- open mouth [1] = function() fb:set(16,z) fb:set(24,z) fb:set(9,c) fb:set(17,c) fb:set(2,c) fb:set(26,c) end diff --git a/draw-oo.lua b/draw-oo.lua index d0d6c53..7941753 100644 --- a/draw-oo.lua +++ b/draw-oo.lua @@ -1,6 +1,6 @@ - return function(t,fb,g,r,b) + return function(t,fb,p) fb:fill(0,0,0) - local c = string.char(g,r,b) + local c = p[1] fb:set( 2,c) fb:set( 3,c) fb:set( 6,c) fb:set( 7,c) fb:set( 9,c) fb:set(12,c) fb:set(13,c) fb:set(16,c) fb:set(17,c) fb:set(20,c) fb:set(21,c) fb:set(24,c) diff --git a/draw-shifty.lua b/draw-shifty.lua index 6e4f1f0..f9823e5 100644 --- a/draw-shifty.lua +++ b/draw-shifty.lua @@ -1,7 +1,7 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) local ix = 0 - local c = string.char(g,r,b) + local c = p[1] fb:set( 2,c) fb:set( 3,c) fb:set( 6,c) fb:set( 7,c) fb:set( 9,c) fb:set(12,c) fb:set(13,c) fb:set(16,c) fb:set(17,c) fb:set(19,c) fb:set(20,c) fb:set(21,c) diff --git a/draw-shifty2.lua b/draw-shifty2.lua index 30f39cf..30a8d2a 100644 --- a/draw-shifty2.lua +++ b/draw-shifty2.lua @@ -1,7 +1,7 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) local ix = 0 - local c = string.char(g,r,b) + local c = p[1] local x = string.char(0,0,0) fb:set( 3,c) fb:set( 8,c) fb:set(10,c) fb:set(15,c) fb:set(17,c) fb:set(18,c) fb:set(22,c) fb:set(23,c) diff --git a/draw-snake.lua b/draw-snake.lua index c4a191e..0d5d31f 100644 --- a/draw-snake.lua +++ b/draw-snake.lua @@ -1,6 +1,6 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) local ix = 0 - local c = string.char(g,r,b) + local c = p[1] fb:fill(0,0,0) fb:set(25,c) fb:set(26,c) fb:set(19,c) fb:set(28,c) fb:set(29,c) fb:set(30,c) fb:set(23,c) fb:set(15,c) fb:set(7,c) fb:set(8,c) diff --git a/draw-snake2.lua b/draw-snake2.lua index 796e2fe..1914ba2 100644 --- a/draw-snake2.lua +++ b/draw-snake2.lua @@ -1,14 +1,18 @@ -- a more curious snake with occasional red "heart" nearby -- +-- Palette: snake, heart +-- +-- -- 1 2 3 4 5 6 7 8 -- 00 o o o o o h x h -- 08 o o o o o e x o -- 16 w w w w o o x o -- 24 w w w w x x x o -- -return function(t,fb,g,r,b) +return function(t,fb,p) local ix = 2 -- since we start effectively in state 1... - local c = string.char(g,r,b) + local c = p[1] + local h = p[2] or string.char(0,15,0) -- heart defaults red local z = string.char(0,0,0) local ft = { -- flatten out [1] = function() fb:set(25,c) fb:set(27,c) fb:set(17,z) fb:set(19,z) end @@ -19,7 +23,7 @@ return function(t,fb,g,r,b) -- look forward , [3] = function() fb:set(6,z) fb:set(8,c) end -- heart on (like what we see) - , [4] = function() fb:set(14,0,15,0) end + , [4] = function() fb:set(14,h) end -- slither 1 , [5] = function() fb:set(20,c) fb:set(28,z) end -- slither 2 diff --git a/draw-staryeyes.lua b/draw-staryeyes.lua index a5443be..ab0962a 100644 --- a/draw-staryeyes.lua +++ b/draw-staryeyes.lua @@ -1,5 +1,8 @@ -return function(t,fb,g,r,b) - local c = string.char(g,r,b) +return function(t,fb,p) + local c = p[1] + local g = p[1]:byte(1) + local r = p[1]:byte(2) + local b = p[1]:byte(3) local cmax = math.max(r,g,b) local i,v @@ -15,7 +18,7 @@ return function(t,fb,g,r,b) for i,v in ipairs{...} do fb:set(v,ag,ar,ab) end end - local function drawEq() for i,v in ipairs({3,6}) do fb:set(v,g,r,b) end end + local function drawEq() for i,v in ipairs({3,6}) do fb:set(v,c) end end local function drawTwinkleEyes() drawbiased(3,6) end local ft = { [0] = drawEq, drawEq, drawTwinkleEyes } fb:fill(0,0,0) diff --git a/draw-together.lua b/draw-together.lua index 385078f..810713d 100644 --- a/draw-together.lua +++ b/draw-together.lua @@ -1,6 +1,8 @@ -- Two hands animate together, heartbeat, then repeat at offset (to average -- out the symmetry breaking) - +-- +-- Palette: together, left, right +-- -- 1 2 3 4 5 6 7 8 -- 1 2 3 4 5 6 7 8 -- 1 2 3 4 5 6 7 8 -- 00 o 1 o o o o 1 o -- 00 o o 2 o o 2 o o -- 00 o o 3 o 3 o o o -- 08 1 o o o o o o 1 -- 08 o 2 o o o o 2 o -- 08 o 3 o 3 o 3 o o @@ -9,18 +11,31 @@ -- (or shifted right one) -return function(t,fb,g,r,b) +return function(t,fb,p) local k,v - local c = string.char(g,r,b) + local c = p[1] + local c2 = p[2] or c + local c3 = p[3] or c local offset = 0 local ft = { -- animate together - function() fb:fill(0,0,0) for k,v in ipairs({2,7,9,16,18,23,27,30}) do fb:set(v,c) end end, + function() fb:fill(0,0,0) + for k,v in ipairs({2,9,18,27}) do fb:set(v,c2) end -- left + for k,v in ipairs({7,16,23,30}) do fb:set(v,c3) end -- right + end, function() end, - function() fb:fill(0,0,0) for k,v in ipairs({3,6,10,15,19,22,28,29}) do fb:set(v,c) end end, + function() fb:fill(0,0,0) + for k,v in ipairs({3,10,19,28}) do fb:set(v,c2) end -- left + for k,v in ipairs({6,15,22,29}) do fb:set(v,c3) end -- right + end, function() end, + function() fb:fill(0,0,0) + for k,v in ipairs({3,10,19}) do fb:set(v+offset,c2) end -- left + for k,v in ipairs({5,14,21}) do fb:set(v+offset,c3) end -- right + for k,v in ipairs({12,28}) do fb:set(v+offset,c) end -- both + end, + -- all the both color function() fb:fill(0,0,0) for k,v in ipairs({3,5,10,12,14,19,21,28}) do fb:set(v+offset,c) end end, - function() end, -- beat function() fb:set(11+offset,c) fb:set(13+offset,c) end, function() fb:set(11+offset,0,0,0) fb:set(13+offset,0,0,0) fb:set(20+offset,c) end, diff --git a/draw-xx.lua b/draw-xx.lua index 87ff53f..4bf40de 100644 --- a/draw-xx.lua +++ b/draw-xx.lua @@ -1,6 +1,6 @@ -return function(t,fb,g,r,b) +return function(t,fb,p) fb:fill(0,0,0) - local c = string.char(g,r,b) + local c = p[1] fb:set( 1,c) fb:set( 4,c) fb:set( 5,c) fb:set( 8,c) fb:set(10,c) fb:set(11,c) fb:set(14,c) fb:set(15,c) fb:set(18,c) fb:set(19,c) fb:set(22,c) fb:set(23,c) diff --git a/init2.lua b/init2.lua index 046eba8..a4a871a 100644 --- a/init2.lua +++ b/init2.lua @@ -13,7 +13,7 @@ remoteqtmrs = {} isTouch = false pendRemoteMsg = nil -local function drawfailsafe(t,fb,g,r,b) fb:fill(g,r,b) end +local function drawfailsafe(t,fb,p) fb:fill(p[1]:byte(1),p[1]:byte(2),p[1]:byte(3)) end function loaddrawfn(name) local f = loadfile (string.format("draw-%s.lc",name)) local fn = f and f() diff --git a/lamp-remote.lua b/lamp-remote.lua index c3f3da7..7de7b0f 100644 --- a/lamp-remote.lua +++ b/lamp-remote.lua @@ -12,7 +12,7 @@ local vt = { ['end'] = function() return true end, -- in means to queue up a timer pointing at a label (which must already be known) - ['in'] = function(s,ls) + ['in'] = function(s,ls,p) local d,l = s:match("^(%d+)%s+(.*)") if d and ls[l] then s = ls[l] @@ -22,21 +22,31 @@ local vt = { remoteqtmrs[tn] = t t:alarm(d,tmr.ALARM_SINGLE,function() remoteqtmrs[tn] = nil - intloop(s,ls) + intloop(s,ls,p) end) end end, + ['color'] = function(s,_,p) + local ix,r,g,b = s:match("^(%w+)%s+(%x+)%s+(%x+)%s+(%x+)%s*$") + ix = tonumber(ix) + if ix then + g = (tonumber(g,16)) or 1; r = (tonumber(r,16)) or 1; b = (tonumber(b,16)) or 1 + p[ix] = string.char(g,r,b) + end + end, + -- draw is the real reason we're here - ['draw'] = function(s) + ['draw'] = function(s,_,p) -- engage a drawing function and post a time event to pop the fifo -- on the next tick (for, e.g., delay's use). This is done on a -- callback to prevent deep stacks. local m,r,g,b = s:match("^(%w+)%s+(%x+)%s+(%x+)%s+(%x+)%s*$") if m then g = (tonumber(g,16)) or 0; r = (tonumber(r,16)) or 0; b = (tonumber(b,16)) or 0 + p[1] = string.char(g,r,b) remotetmr:unregister() - loaddrawfn(m)(remotetmr,remotefb,g,r,b) + loaddrawfn(m)(remotetmr,remotefb,p) remotetmr:start() dodraw() end @@ -44,10 +54,10 @@ local vt = { } -- loop over all ;-delimited statements in the message and fire them off. -function intloop(msg,labels) +function intloop(msg,labels,palette) local c,as for c,as in msg:gmatch("(%w*)%s*([^;]*);%s*") do - if c and vt[c] then if vt[c](as,labels) then break end end + if c and vt[c] then if vt[c](as,labels,palette) then break end end end end @@ -71,5 +81,5 @@ return function(msg) end end - intloop(msg,labels) + intloop(msg,labels,{}) end diff --git a/lamp-touch.lua b/lamp-touch.lua index 2564a5a..715a43f 100644 --- a/lamp-touch.lua +++ b/lamp-touch.lua @@ -182,7 +182,7 @@ local function ontouch() if ledfb == touchfb then touchtmr:unregister() touchlastfn = touchfns[touchfnix] - loaddrawfn(touchlastfn)(touchtmr,touchfb,touchcolorvec(touchcolor)); dodraw() + loaddrawfn(touchlastfn)(touchtmr,touchfb,{string.char(touchcolorvec(touchcolor))}); dodraw() touchtmr:start() end end -- 2.50.1