--- /dev/null
+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
-- 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)
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)