]> hydra-www.ietfng.org Git - acmetensortoys-esp-lua_lamp/commitdiff
heartstream: new drawing
authorNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Mon, 20 Nov 2017 08:19:39 +0000 (03:19 -0500)
committerNathaniel Wesley Filardo <nwf@cs.jhu.edu>
Mon, 20 Nov 2017 08:21:24 +0000 (03:21 -0500)
Catch linux-draw-xpm.lua's emulation of the framebuffer up to enable
:shift() calls.

draw-heartstream.lua [new file with mode: 0644]
linux-draw-xpm.lua

diff --git a/draw-heartstream.lua b/draw-heartstream.lua
new file mode 100644 (file)
index 0000000..d972719
--- /dev/null
@@ -0,0 +1,54 @@
+return function(t,fb,p)
+  local c = p[1]
+  local c2 = p[2] or c
+  local z = string.char(0,0,0)
+
+  local s = {}
+  local b = {}
+
+  -- fill sequence table
+  local ft = { [1] = function() local k,v for k,v in ipairs(s) do fb:set(8  + v,c2) end end, -- side chambers
+               [2] = function() local k,v for k,v in ipairs(s) do fb:set(8  + v,z)  end
+                                local k,v for k,v in ipairs(b) do fb:set(16 + v,c2) end end, -- bottom chambers
+               [3] = function() local k,v for k,v in ipairs(b) do fb:set(16 + v,z)  end end, -- empty
+               [4] = function()                                                         end  -- stay empty
+             }
+
+  -- heart sequence table (leftmost column only; see use of fb:shift below)
+  local ht = { [1] = function() fb:set(9,c)              end,
+               [2] = function() fb:set(1,c) fb:set(17,c) table.insert(s,1,1) end,
+               [3] = function() fb:set(9,c) fb:set(25,c) table.insert(b,1,1) end,
+               [4] = function() fb:set(1,c) fb:set(17,c) table.insert(s,1,1) end,
+               [5] = function() fb:set(9,c)              end,
+               [6] = function()                          end,
+             }
+
+  -- update fill positions when advancing frame
+  local function fm()
+    local k,v
+    for k,v in ipairs(b) do if v == 8 then table.remove(b,k) else b[k] = v+1 end end
+    for k,v in ipairs(s) do if v == 8 then table.remove(s,k) else s[k] = v+1 end end
+  end
+
+  fb:fill(0,0,0)
+
+  local tix = 0
+  local fix = #ft
+  local hix = 1
+  t:register(150,tmr.ALARM_AUTO,function()
+    fm() ; fb:set(8,z) fb:set(16,z) fb:set(24,z) ; fb:shift(1,ws2812.SHIFT_LOGICAL)
+
+    -- heart positions
+    ht[hix]()
+    hix = (hix == #ht and 1) or hix + 1
+
+    -- fill positions always render (may be superfluous)
+    tix = (tix + 1) % 3
+    if tix == 0 then
+      fix = (fix == #ft and 1) or fix + 1
+    end
+    ft[fix]()
+
+    dodraw()
+  end)
+end
index ef772a1199495b6ddf5fe57d7509fc7015be915d..96ed161a65e0f17e76450bc3750badaf0d89783b 100644 (file)
@@ -1,4 +1,8 @@
 -- emulate enough framebuffer functionality
+ws2812 = {}
+ws2812.SHIFT_LOGICAL = 0
+ws2812.SHIFT_CIRCULAR = 1
+
 remotefb.length = 32
 function remotefb.set(self,ix,a1,a2,a3)
   -- printerr(ix,a1,a2,a3)
@@ -22,6 +26,31 @@ function remotefb.fill(self,...)
   local i
   for i = 1,self.length do self:set(i,...) end
 end
+function remotefb.shift(self,n,m,i,j)
+  if      j == nil then j = self.length
+   elseif j < 0    then j = self.length - j
+                        if j <= 0 then return end
+   elseif j == 0 then return
+   elseif j > self.length then return
+  end
+  if      i == nil then i = 1
+   elseif i < 0    then i = self.length - i
+                        if i <= 0 then return end
+   elseif i == 0 then return
+   elseif i > self.length then return
+  end
+
+  if m == nil then m = remotefb.SHIFT_LOGICAL end
+
+  local ix
+
+  for ix = 1, n do
+    local v = table.remove(self,j)
+    if m == ws2812.SHIFT_LOGICAL then v = string.char(0,0,0) end
+
+    table.insert(self,i,v)
+  end
+end
 
 local function drawfailsafe(t,fb,g,r,b) fb:fill(0,0,0) end
 function loaddrawfn(name)