Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local curCols = {}
- buffer_details = {1, 1, colors.black, colors.white, nil}
- local sw,sh = term.getSize()
- local function split(str, pat)
- local t = {} -- NOTE: use {n = 0} in Lua-5.0
- if str ~= nil then
- local fpat = "(.-)" .. pat
- local last_end = 1
- local s, e, cap = str:find(fpat, 1)
- while s do
- if s ~= 1 or cap ~= "" then
- table.insert(t,cap)
- end
- last_end = e+1
- s, e, cap = str:find(fpat, last_end)
- end
- if last_end <= #str then
- cap = str:sub(last_end)
- table.insert(t, cap)
- end
- else
- print("##ERROR failed to split ["..str.."] by:"..pat)
- end
- return t
- end
- function getColorTab(char, background, text)
- if curCols[char] ~= nil then
- if curCols[char][background] ~= nil then
- if curCols[char][background][text] ~= nil then
- return curCols[char][background][text]
- end
- end
- end
- return nil
- end
- function addColorTab(col)
- local char = col.char
- local background = col.background
- local text = col.text
- if getColorTab(char, background, text) == nil then
- if curCols[char] == nil then curCols[char] = {} end
- if curCols[char][background] == nil then curCols[char][background] = {} end
- curCols[char][background][text] = col
- return true
- end
- return false
- end
- function createColor(char, background, text)
- --sleep(0)
- local col = getColorTab(char, background, text)
- if col == nil then
- col = {}
- col.char = char
- col.background = background
- col.text = text
- addColorTab(col)
- end
- return col
- end
- function createPixel(x, y, col)
- local pixel = {}
- pixel.x = x
- pixel.y = y
- pixel.col = col
- pixel.compare = function(self, col)
- return self.col == col
- end
- return pixel
- end
- function createBuffer()
- local buffer = {}
- buffer.width = sw
- buffer.height = height
- buffer.changes = {}
- buffer.changed = {}
- buffer.term = term
- buffer.tick = 0
- buffer.amt = 0
- buffer.res = 1
- buffer_details[5] = buffer
- for x=1,sw do
- buffer[x] = {}
- buffer.changes[x] = {}
- for y=1,sh do
- --print("x="..x..", y="..y)
- buffer[x][y] = createPixel(x, y, createColor(" ", colors.black, colors.white))
- buffer.changes[x][y] = false
- end
- end
- buffer.get = function(self, x, y)
- if self[x] ~= nil then
- if self[x][y] ~= nil then
- return self[x][y]
- end
- end
- return nil
- end
- buffer.check = function(self, x, y)
- if self.changes[x] ~= nil then
- if self.changes[x][y] ~= nil then
- return self.changes[x][y]
- end
- end
- return false
- end
- buffer.set = function(self, x, y, col)
- local pixel = self:get(x,y)
- if pixel ~= nil then
- if not pixel:compare(col) then
- pixel.col = col
- if not self:check(x,y) then
- self.changed[#self.changed + 1] = {x,y}
- if self.changes[x] == nil then self.changes[x] = {} end
- self.changes[x][y] = true
- end
- end
- end
- end
- buffer.renderPixel = function(self, x, y)
- self.changes[x][y] = false
- local pixel = self[x][y]
- for px = (pixel.x*self.res)-(self.res-1), pixel.x*self.res do
- for py = (pixel.y*self.res)-(self.res-1), pixel.y*self.res do
- self.term.setCursorPos(px, py)
- self.term.setBackgroundColor(pixel.col.background)
- self.term.setTextColor(pixel.col.text)
- self.term.write(pixel.col.char)
- end
- end
- end
- buffer.render = function(self, fps)
- for i=1,#self.changed do
- local pos = self.changed[i]
- self:renderPixel(pos[1], pos[2])
- end
- self.amt = self.amt + #self.changed
- self.tick = self.tick + 1
- if self.tick >= 10 then
- term.setCursorPos(1, 13)
- term.setBackgroundColor(colors.black)
- term.setTextColor(colors.white)
- --print(self.amt.." pixels/sec")
- self.tick = 0
- self.amt = 0
- end
- self.changed = {}
- end
- buffer.setBuffer = function(self)
- buffer_detials[5] = self
- end
- buffer.setCursorPos = function(x, y)
- buffer_details[1] = x
- buffer_details[2] = y
- end
- buffer.setBackgroundColor = function(col)
- buffer_details[3] = col
- end
- buffer.setTextColor = function(col)
- buffer_details[4] = col
- end
- buffer.getSize = function()
- local buffer = buffer_details[5]
- if buffer == nil then print("NIL_BUFFER") end
- return buffer_details[5].width, buffer_details[5].height
- end
- buffer.write = function(char)
- char = char:sub(1,1)
- local col = createColor(char, buffer_details[3], buffer_details[4])
- local buffer = buffer_details[5]
- if buffer ~= nil then
- buffer:set(buffer_details[1], buffer_details[2], col)
- end
- end
- buffer.writeLine = function(str)
- local buffer = buffer_details[5]
- local x, y = buffer_details[1], buffer_details[2]
- for i=1,str:len() do
- buffer.setCursorPos(x+i-1, y)
- buffer.write(str:sub(i, i))
- end
- end
- buffer.clear = function()
- buffer_details[5]:reset()
- end
- buffer.reset = function(self)
- local buffer = self
- for x=1,self.width do
- buffer[x] = {}
- buffer.changes[x] = {}
- for y=1,sh do
- --print("x="..x..", y="..y)
- local pixel = createPixel(x, y, createColor(" ", buffer_details[3], colors.white))
- term.setCursorPos(x, y)
- term.setBackgroundColor(pixel.col.background)
- term.setTextColor(pixel.col.text)
- term.write(pixel.col.char)
- buffer[x][y] = pixel
- buffer.changes[x][y] = false
- end
- end
- buffer.changes = {}
- buffer.changed = {}
- end
- return buffer
- end
- local buffer = createBuffer()
- local on = true
- local w, h = term.getSize()
- local function createAnimation(frames)
- local ani = {
- image = {}, -- {background, text, colour}
- curImage = {},
- frames = frames, -- { {x, y}, {background, text, colour} }
- frame = 1,
- paint = {colors.white, colors.black, " "},
- cloneImage = function(self)
- local curImage = {}
- for x=1,#self.image do
- local tab = self.image[x]
- curImage[x] = {}
- for y=1,#tab do
- local col = self.image[x][y]
- curImage[x][y] = {unpack(col)}
- end
- end
- return curImage
- end,
- resetImage = function(self)
- for x=1,w-1 do
- self.image[x] = {}
- for y=1,h-5 do
- self.image[x][y] = {unpack(self.paint)}
- end
- end
- self.curImage = self:cloneImage()
- self.frame = 1
- end,
- renderEverything = function(self, playing)
- self:render()
- self:renderFrameSelecter(playing)
- self:renderPaintSelecter()
- buffer:render()
- end,
- render = function(self)
- for x=1,#self.curImage do
- local tab = self.curImage[x]
- for y=1,#tab do
- local col = tab[y]
- buffer.setCursorPos(x, y+2)
- buffer.setBackgroundColor(col[1])
- buffer.setTextColor(col[2])
- buffer.write(col[3])
- end
- end
- end,
- setBackground = function(self, colour)
- self.paint[1] = colour
- end,
- setText = function(self, colour)
- self.paint[2] = colour
- end,
- setChar = function(self, char)
- self.paint[3] = char
- end,
- paintPoint = function(self, x, y)
- y = y - 2
- --[[if self.frame == 1 then
- if self.image[x] ~= nil then
- if self.image[x][y] ~= nil then
- self.image[x][y] = {unpack(self.paint)}
- end
- end
- self.curImage = self:cloneImage()
- else]]
- if self.frames[self.frame] == nil then self.frames[self.frame] = {} end
- local tab = self.frames[self.frame]
- tab[#tab + 1] = { {x, y}, {unpack(self.paint)} }
- local old = self.frame
- if self.frame > 1 then
- self:setFrame(1)
- self.frame = 1
- end
- self:setFrame(old)
- self.frame = old
- --end
- end,
- renderPaintSelecter = function(self)
- for y=1,16 do
- buffer.setCursorPos(w, y)
- buffer.setBackgroundColor(2^(y-1))
- buffer.write(" ")
- end
- buffer.setCursorPos(w-1, h-3)
- buffer.setBackgroundColor(self.paint[1])
- buffer.setTextColor(self.paint[2])
- buffer.write(self.paint[3])
- end,
- drawFrame = function(self, f)
- local frame = self.frames[f]
- if frame ~= nil then
- for i=1,#frame do
- local info = frame[i]
- local pos = info[1]
- local col = info[2]
- self.curImage[pos[1]][pos[2]] = {unpack(col)}
- end
- end
- --self.frame = f
- end,
- setFrame = function(self, f)
- if f <= self.frame then
- self.curImage = self:cloneImage()
- for i=1,f do
- self:drawFrame(i)
- end
- elseif f > self.frame then
- for i=self.frame+1,f do
- self:drawFrame(i)
- end
- end
- if self.frame ~= 1 and self.frames[self.frame] == nil then self.frames[self.frame] = {} end
- end,
- getFrame = function(self, i1, i2, i3) --i1 is bar 1, i2 is bar 2, i3 = bar 3
- local frame = ( (i3-1) * w * w ) + ( (i2-1) * w ) + i1
- return frame
- end,
- getFrameBreakdown = function(self, frame)
- local f1 = frame % (w * w)
- local i3 = ((frame - f1) / (w * w))+1
- local f2 = f1 % (w)
- local i2 = ((f1 - f2) / (w))+1
- local i1 = f2
- return i1, i2, i3
- end,
- renderFrameSelecter = function(self, playing)
- local i1, i2, i3 = self:getFrameBreakdown(self.frame)
- local cols = {
- { colors.lightGray, colors.lightBlue, "-", "+" },
- { colors.lightGray, colors.blue, "-", "+" },
- { colors.lightGray, colors.black, "-", "+" }
- }
- if playing then
- for i=1,#cols do cols[i][1] = colors.red end
- end
- local is = {i1, i2, i3}
- for x=1,w do
- for off=-2,0 do
- buffer.setBackgroundColor(cols[off+3][1])
- buffer.setTextColor(cols[off+3][2])
- local char = cols[off+3][3] if x == is[off+3] then char = cols[off+3][4] end
- buffer.setCursorPos(x, h+off)
- buffer.write(char)
- end
- end
- end,
- click = function(self, x, y, button)
- if y >= h-2 then --selected frame
- local i = 3 - (h - y)
- local ifs = {self:getFrameBreakdown(self.frame)}
- ifs[i] = x
- local nframe = self:getFrame(unpack(ifs))
- self:setFrame(nframe)
- self.frame = nframe
- elseif x == w then
- if button == 1 then
- self:setBackground(2^(y-1))
- elseif button == 2 then
- self:setText(2^(y-1))
- end
- else
- self:paintPoint(x, y)
- end
- end,
- playAnimation = function(self, pause)
- --self:setFrame(1)
- --self.frame = 1
- local ison = true
- local timer = os.startTimer(pause)
- self:renderEverything(true)
- while ison do
- local event, p1, p2, p3 = os.pullEvent()
- if event == "timer" and p1 == timer then
- self:setFrame(1)
- local old = self.frame
- self.frame = 1
- self:setFrame(old)
- self.frame = old + 1
- if self.frame >= w^3 then ison = false end
- self:renderEverything(true)
- timer = os.startTimer(pause)
- elseif event == "key" then
- if p1 == 29 then ison = false end
- end
- end
- on = true
- runAnimationProgram()
- end,
- }
- if ani.frames == nil then ani.frames = {} end
- return ani
- end
- local function getSize(tab)
- local size = 0
- for k,v in pairs(tab) do if v ~= nil then size = size + 1 end end
- return size
- end
- local function form(tab, space)
- --[[if space == nil then space = "" end
- local str = space.." {"
- for k,v in pairs(tab) do
- if type(v) == "table" then
- str = str..", "..form(v, " ")
- else
- str = str..", "..tostring(v)
- end
- end
- return str.." } \n"]]
- return textutils.serialize(tab)
- end
- local function loadFrames(dir)
- local frames = {} -- contains frames[index] = {}
- -- contains {frame_info1, frame_info2, .. frame_infon}
- -- frame_info = { {x, y}, {background, text, char} }
- local file = fs.open(dir, "r")
- local line = file.readLine()
- while line ~= nil do
- local sp1 = split(line, "==")
- local index = tonumber(sp1[1])
- if frames[index] == nil then frames[index] = {} end
- local frame = frames[index]
- if sp1[2] ~= nil and sp1[2] ~= "" then
- local sp2 = split(sp1[2], "::")
- local pos = split(sp2[1], ",")
- local background = tonumber(sp2[2])
- local text = tonumber(sp2[3])
- local char = tostring(sp2[4])
- --print(pos[1]..","..pos[2]..":"..background..":"..text..":"..char)
- frames[index][#frames[index] + 1] = { {tonumber(pos[1]), tonumber(pos[2])}, {background, text, char} }
- end
- frames[index] = frame
- --print("f:"..#frame..", "..index)
- line = file.readLine()
- end
- file.close()
- --print("frames:"..getSize(frames))
- --sleep(1)
- return frames
- end
- local animation = createAnimation()
- local function saveFrames(dir, frames)
- local file = fs.open(dir, "w")
- for i=1,w^3 do
- local frame = frames[i]
- if frame ~= nil then
- for j=1,#frame do
- local info = frame[j]
- local pos = info[1]
- local col = info[2]
- --local str = i.."=="..pos[1]..","..pos[2].."::"..col[1].."::"..col[2].."::"..col[3]
- local str = i.."=="
- str = str..pos[1]..","
- str = str..pos[2].."::"
- str = str..col[1].."::"
- str = str..col[2].."::"
- str = str..col[3]
- file.writeLine(str)
- end
- end
- end
- file.close()
- end
- animation:resetImage()
- animation:drawFrame(1)
- local function fillString(str, w)
- local nstr = str
- while nstr:len() < w do nstr = nstr.." " end
- return nstr
- end
- local input = ""
- local msg = ""
- local function drawMenu()
- buffer.setCursorPos(1,1)
- buffer.setBackgroundColor(colors.lightGray)
- buffer.setTextColor(colors.blue)
- buffer.writeLine(fillString("| SAVE | OPEN | CLEAR | CLEAR ALL | "..msg, w-1))
- buffer.setCursorPos(1,2)
- buffer.writeLine(fillString("| INPUT: "..input, w-1))
- end
- local function checkMenu(x, y)
- if y == 2 then
- term.setBackgroundColor(colors.lightGray)
- term.setTextColor(colors.blue)
- term.setCursorPos(1, 2)
- term.write(fillString("| INPUT: ", w-1))
- term.setCursorPos(("| INPUT: "):len(), 2)
- input = read()
- elseif y == 1 then
- if x >= 1 and x < 8 then --save
- saveFrames(input, animation.frames)
- msg = "FILE SAVED"
- elseif x >= 8 and x < 15 then --open
- animation.frames = loadFrames(input)
- animation:resetImage()
- animation:setFrame(1)
- animation.frame = 1
- drawMenu()
- animation:renderEverything(false)
- msg = "FILE OPENED"
- elseif x >= 15 and x < 23 then --clear
- animation.frames[animation.frame] = {}
- msg = "FRAME CLEARED"
- elseif x >= 23 and x < 35 then --clear all
- animation:resetImage()
- animation.frames = {}
- msg = "ALL CLEARED"
- end
- end
- end
- drawMenu()
- animation:renderEverything(false)
- function runAnimationProgram()
- local doAni = false
- animation:renderEverything(false)
- while on do
- local event, p1, p2, p3 = os.pullEvent()
- if event == "mouse_click" or event == "mouse_drag" then
- animation:click(p2, p3, p1)
- checkMenu(p2, p3)
- drawMenu()
- animation:renderEverything(false)
- elseif event == "key" then
- if p1 == 29 then
- on = false
- elseif p1 == 56 then
- doAni = true
- on = false
- animation:renderEverything(false)
- end
- elseif event == "char" then
- animation:setChar(p1)
- end
- end
- if doAni then animation:playAnimation(0.1) end
- end
- runAnimationProgram()
- term.setBackgroundColor(colors.black)
- term.clear()
- term.setCursorPos(1, 1)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement