5bitesofcookies

Buffersystem-cc

Oct 21st, 2015
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 17.79 KB | None | 0 0
  1. local clrLk = {}
  2. for n=1,16 do
  3.     clrLk[2^(n-1)] = string.sub( "0123456789abcdef",n,n )
  4. end
  5. local invLk = {}
  6. for i=1,16 do
  7.     invLk[string.sub( "0123456789abcdef",i,i )] = 2^(i-1)
  8. end
  9. --CONFIG:
  10. local lazy = false
  11. --[[?:
  12. lazy is weather or not write will precalculate string replacement. If you're blitting a lot, turn this off. If you're using mostly
  13. active buffers, turn this on. This will:
  14. Speed up writing
  15. Slows down bliting(only happens when pulling up a previously off-screen application)
  16. Eat up more memory(a decent bit--this will keep lazilly adding stuff to a table rather than calculating it.)
  17. If you're bliting a lot, you probably want to set it to false
  18.  
  19.  
  20. Default value: false
  21.  
  22. ]]
  23. --[[A NOTE ON EXESSIVE OP COUNT INCRECIMENT:
  24. Due to the way Lua works, if you get a rediculously high number(like, if you left something running without ever de-foucusing and re-foucusing it for several months), this script WILL break.
  25. That said, if you ever get a legitiment case of this happening, let me know.
  26. ]]
  27. local function yield()
  28.     os.queueEvent"bufferYield"
  29.     os.pullEvent"bufferYield"
  30. end
  31. local function clearRealdisp(self)
  32.     for i=1,self.sizey do
  33.         game.l("wiope "..i+self.pY)
  34.         self.t.clearLine(i+self.pY)
  35.     end
  36. end
  37. --[[ idk wtf this is, but I'm afriad to delete it ._.
  38. if ((b[y] or {})[x] or {}).bg then
  39.         term.setBackgroundColor(b[y][x].bg)
  40.     end
  41.     if ((b[y] or {})[x] or {}).tx then
  42.         term.setTextColor(b[y][x].tx)
  43.     end ]]
  44. function newBuf(w,h,nativeT)
  45.     game.l"newBuf"
  46.     local a,b = term.getSize()
  47.     w,h = (w or a),(h or b)
  48.     local self = {}
  49.     local function clearLine(l)
  50.         error"DFGDFGSDFGDFSGF"
  51.         l= l or 1
  52.         local x,y = self.getCursorPos()
  53.         self.t.setBackgroundColor(self.bg)
  54.         for y=1,self.getSize() do
  55.             for i=1,self.sizex do
  56.                 if not (self.nr[l+(self.pX-1)] or {})[(self.pX-1)+i] then
  57.                     self.t.setCursorPos((self.pX-1)+i,l+(self.pY-1))
  58.                     self.t.write" "
  59.                 end
  60.             end
  61.            
  62.         end
  63.         --term.setBackgroundColor(colors.black)
  64.         self.t.write(white)
  65.         self.t.setCursorPos(x,y)
  66.     end
  67.     local function refreshY(ry,Y,x,y)
  68.         local tx,ty = term.getSize()
  69.         if self[ry] then --px is the x position for next write to, Y is the part of the screen on the real terminal t write to, X is the part of the real screen to write to, rx & ry are the parts of the buffer,
  70.             local txt,tColor,bColor = "","",""
  71.             local px =1
  72.             for X=1+x,tx+x do
  73.                 local rx = X-x
  74. --              game.l("rx : "..rx.." ry "..ry.." X "..X.." Y "..Y)
  75.                 if (self.nr[ry] or {})[rx] then
  76.                     game.l"caught"
  77.                     if txt~="" then --We need to blit stuff before the nozone, if there is anything there.
  78.                         game.l"entr"
  79.                         self.t.setCursorPos(px,Y)
  80.                         self.t.blit(txt,tColor,bColor)
  81.                         --sleep(1)
  82.                         txt,tColor,bColor = "","",""
  83.                     end
  84.                     px=rx+1--The position for the next blit is now set to right after this nozone. This will keep getting set until the last nozone, so the rest of the text comes out right
  85.                 else
  86.                     if self[ry][rx] then
  87.                         txt = txt..self[ry][rx].txt --Add this peice of text (ex. "x") to the line txt, same for text/background colors. In a y:x table
  88.                         tColor = tColor..(clrLk[self[ry][rx].tc] or "0")
  89.                         bColor = bColor..(clrLk[self[ry][rx].bg] or "f")
  90.                     else
  91.                         txt=txt.." "
  92.                         tColor=tColor..clrLk[self.tc]
  93.                         bColor=bColor..clrLk[self.bg]
  94.                     end
  95.                 end  
  96.             end    
  97.             self.t.setCursorPos(px,Y)
  98. --          game.l("t "..tostring(txt).." co "..tostring(tColor).." bCo "..tostring(bColor))
  99.             self.t.blit(txt,tColor,bColor)
  100.  
  101.         end
  102.     end
  103.     local function deepcopy(orig)--taken from http://lua-users.org/wiki/CopyTable
  104.         local orig_type = type(orig)
  105.         local copy
  106.         if orig_type == 'table' then
  107.             copy = {}
  108.             for orig_key, orig_value in next, orig, nil do
  109.                 copy[deepcopy(orig_key)] = deepcopy(orig_value)
  110.             end
  111.             setmetatable(copy, deepcopy(getmetatable(orig)))
  112.         else -- number, string, boolean, etc
  113.             copy = orig
  114.         end
  115.         return copy
  116.     end
  117.     function self.getSize()
  118.         return self.sizex,self.sizey
  119.     end
  120.     function self.resize(x,y)
  121.         game.l"resize"
  122.         if type(x)~="number" or type(y)~="number"then
  123.             return error"[buffer][resize] - Expected number, number"
  124.         end
  125.         self.sizex,self.sizey = x,y
  126.         self.bufferblit()
  127.     end
  128.     function self.setCursorPos(x,y)
  129.         if y < 1 or y > self.sizey then
  130.             y = -666
  131.         end
  132.         --game.l("set "..x.." y "..y)
  133.         if type(x)~="number" or type(y)~="number"then
  134.             return error"[buffer][setCursorPos] - Expected number, number"
  135.         end
  136.         x,y=math.floor(x),math.floor(y)
  137.         self.x,self.y=x,y
  138.         if self.isActive then
  139.             self.t.setCursorPos(x+(self.pX-1),y+(self.pY-1))
  140.         end
  141.     end
  142.     function self.getCursorPos()
  143.         return self.x,self.y
  144.     end
  145.     function self.setBackgroundColor(color)
  146.         self.bg = color
  147.         if self.isActive then
  148.             self.t.setBackgroundColor(color)
  149.         end
  150.     end
  151.     function self.setTextColor(color)
  152.         self.tc = color
  153.         if self.isActive then
  154.             self.t.setTextColor(color)
  155.         end
  156.     end
  157.     function self.getTextColor(color)
  158.         return self.tc
  159.     end
  160.     function self.getBackgroundColor(color)
  161.         return self.bg
  162.     end
  163.  
  164.     function self.setCursorBlink(a)
  165.         self.cursorBlink = a
  166.         if self.isActive then
  167.             self.t.setCursorBlink(a)
  168.         end
  169.     end
  170.     function self.scroll(ammount)
  171.         game.l("scrl "..ammount)
  172.         ammount = ammount or 1
  173.         for i=1,table.maxn(self) do
  174.             self[i]=nil
  175.             self[i] = deepcopy(self[i+ammount]) or {}
  176.         end
  177.         self[0] = nil
  178.         self[#self] = nil
  179.         self[#self+1]={}
  180.         if self.isActive then
  181.             --clear the actual term:
  182.         --[[    for i=1,self.sizey+1 do
  183.                 clearLine(i)
  184.             end]]
  185.             self.bufferblit(self.pX-1,self.pY-1)
  186.             self.setCursorPos(1,self.sizey)
  187.         end
  188.     end
  189.     function self.current()
  190.         return self
  191.     end
  192.     function self.makeActive(pX,pY)
  193.         game.l"mkAct"
  194.         self.isActive,self.pX,self.pY = true,pX or (self.pX or 1),pY or (self.pY or 1)
  195.         self.bufferblit(self.pX-1,self.pY-1)
  196.         self.t.setCursorPos(self.x+self.pX-1,self.y+self.pY-1)
  197.         self.t.setCursorBlink(self.cursorBlink)
  198.     end
  199.     function self.setActivePos(pX,pY)
  200.         self.pX,self.pY = pX or self.pX,pY or self.pY
  201.     end
  202.     function self.makeInactive()
  203.         self.isActive = false
  204.         if self.isActive then
  205.             os.shutdown()
  206.         end
  207.     end
  208.     self.setTextColour = self.setTextColor
  209.     self.setBackgroundColour = self.setBackgroundColor
  210.     self.getTextColour = self.getTextColor
  211.     self.getBackgroundColour = self.getBackgroundColor
  212.     function self.isColor(color)
  213.         return self.t.isColor(color)    
  214.     end
  215. --old writing method
  216.         --[[
  217.         if self.lazy then
  218.             self[self.y] = self[self.y] or {}
  219.             self[self.y][self.x] = self[self.y][self.x] or {}
  220.             self[self.y][self.x][self.opCount] = {}
  221.             --self[self.y][self.x][self.opCount].t = p
  222.             self[self.y][self.x][self.opCount].bg = self.bg
  223.             self[self.y][self.x][self.opCount].tc = self.tc
  224.             self[self.y][self.x][self.opCount].txt = txt
  225.             self.opCount = self.opCount+1
  226.         else
  227.             --self.t.write"l"-------------------------------------------------------------------
  228.             local oldTxt,oldbg,oldtc
  229.             if (self[self.y] or {})[self.x] then
  230.                 oldTxt,oldbg,oldtc=self[self.y][self.x].txt,self[self.y][self.x].bg,self[self.y][self.x].tc
  231.             end
  232.             oldTxt = nil
  233.             --game.l"old"-------------------------------------------------------------------
  234.             --self.t.write(self)
  235.             self[self.y] = self[self.y] or {}
  236.             --game.l"1"--------------------------------------------------------------------------------------------------------------------------------------
  237.             self[self.y][self.x] = self[self.y][self.x] or {}
  238.             --self.t.write"2"---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  239.             self[self.y][self.x].txt = txt
  240.             --self.t.write"3"----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  241.             self[self.y][self.x].bg = self.bg
  242.             --game.l"4"-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  243.             self[self.y][self.x].tc = self.tc
  244.            
  245.             --game.l"str"------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
  246.             local left = string.sub(oldTxt or "",#txt,#(oldTxt or ""))
  247.             --game.l"man"-------------------------------------------------------------------
  248.             if #left>1 then
  249.                 --game.l"left"
  250.                 --self.t.write("     "..self.y)-------------------------------------------------------------------
  251.                 --self.t.write("    "..self.x+#txt)-------------------------------------------------------------------
  252.                 --self.t.write("    "..left)-------------------------------------------------------------------
  253.                 self[self.y] = self[self.y] or {}
  254.                 self[self.y][self.x+#txt] = self[self.y][self.x+#txt] or {}
  255.  
  256.                 self[self.y][self.x+#txt].txt = left
  257.                 --game.l"left1"
  258.                 self[self.y][self.x+#txt].bg = oldbg
  259.                 self[self.y][self.x+#txt].tc = oldtc
  260.             end
  261.             --clear anything in our path:
  262.             for i=self.x+1,self.x+#txt do
  263.                 self[self.y][i] = nil
  264.             end
  265.             self.x = self.x+#txt--increase x count
  266.         end
  267.         --game.l"bye"-------------------------------------------------------------------
  268.         if self.isActive then
  269.             --game.l"a"-------------------------------------------------------------------
  270.             --self.t.setCursorPos(self.x+self.pX,self.y+self.pY) if the buffer is active, this is not necisary
  271.             --game.l"m"-------------------------------------------------------------------
  272.             --self.t.setBackgroundColor(((self[y] or {})[x] or {}).bg) -- The buffer is active, meaning it should already be set to its own colors
  273.             --self.t.setTextColor((self[y] or {})[x] or {}).tc)
  274.             self.t.write(txt)
  275.         end
  276.         --game.l"{"
  277.         for i=1,#self do
  278.             if self[i] then
  279.                 game.l(textutils.serialize(self[i]))
  280.             end
  281.         end
  282.         game.l"}"]]-----------------------------------------
  283.  
  284.     self.isColour = self.isColor
  285.     function self.newNozone(startx,endx,starty,endy)
  286.         for i=starty,endy do
  287.             self.nr[i] = self.nr[i] or {}
  288.             for o=startx,endx do
  289.                 self.nr[i][o] = true
  290.             end
  291.         end
  292.     end
  293.     function self.destroyNozone(startx,endx,starty,endy) -- With aerosol cans
  294.         for i=starty,endy do
  295.             self.nr[i] = self.nr[i] or {}
  296.             for o=startx,endx do
  297.                 self.nr[i][o] = nil
  298.             end
  299.         end
  300.     end
  301.     local function cAt(txt,num)
  302.         return string.sub(txt,num,num)
  303.     end
  304.    
  305.     function self.write(txt)
  306.         --game.l("x "..tostring(self.x).." y "..tostring(self.y).." write : "..txt)
  307.         if type(txt)~="string" then
  308.             txt = tostring(txt)
  309.         end
  310.         self[self.y]=self[self.y] or {}
  311.         self.nr[self.y]=self.nr[self.y] or {}
  312.         -- We split these up into 2 loops, as it is more effecient to check once than many times during the loop
  313.         local x
  314.        
  315.         if self.isActive and (not shoddyWrite)  then
  316.             --game.l"activeWrite"--------------------------
  317.             --game.l(   "at "..tostring((self.x+self.pX)-1) .. " y "..tostring((self.y+self.pY)-1)   )
  318.             self.t.setBackgroundColor(self.bg)
  319.             self.t.setTextColor(self.tc)
  320.             x = self.x-1
  321.             for i=1,#txt do --Note: Doing this forwards & not checking if the cursor is at the edge does have a slight impact on compatibility if term.write is called through something other than write.
  322.                 x=x+1
  323. --              game.l("r - i "..i.." x "..x.." c "..cAt(txt,i).." ; y "..self.y)
  324.                 self[self.y][x] = {}
  325.                 self[self.y][x].txt = cAt(txt,i)
  326.                 self[self.y][x].bg = self.bg
  327.                 self[self.y][x].tc = self.tc
  328.                 if (self.nr[self.y] or {})[x] then
  329.                     game.l"blockd"
  330.                 else
  331.                     self.t.setCursorPos(((x+self.pX)-1),(self.y+self.pY)-1)
  332.                     self.t.write(cAt(txt,i))
  333.                 end
  334.             end
  335.             --Now, set the X cursor pos to the correct place
  336.             self.x = self.x+#txt
  337.             --game.l(self.x)
  338.         else
  339.             -- C&P'd from above
  340.             for i=1,#txt do
  341.                 x=i+self.x-1
  342.                 self[self.y][x] = {}
  343.                 self[self.y][x].txt = cAt(txt,i)
  344.                 self[self.y][x].bg = self.bg
  345.                 self[self.y][x].tc = self.tc
  346.             end
  347.             --Now, set the X cursor pos to the correct place
  348.             self.x = self.x+#txt
  349.             if self.isActive and shoddyWrite then --Refresh the line if this buffer is active
  350.                 refreshY(self.y,self.y+(self.pY-1),(self.pX-1),(self.pY-1))
  351.             end
  352.         end
  353.     end
  354.     function self.blit(txt,txtCol,backCol)
  355.         --game.l("blit "..txt)
  356.         local cx = self.x --The position to do next blit to
  357.         local btxt,btxtCol,bbackCol = "","",""
  358.         for i=1,#txt do
  359.             self[self.y] = self[self.y] or {}
  360.             self[self.y][self.x+i-1] = {}
  361.             self[self.y][self.x+i-1].bg = invLk[backCol:sub(i,i)]
  362.             self[self.y][self.x+i-1].tc = invLk[txtCol:sub(i,i)]
  363.             self[self.y][self.x+i-1].txt= txt:sub(i,i)
  364.             --game.l(textutils.serialize(self[self.y][self.x+i]))
  365.             if (self.nr[self.y] or {})[self.x+i-1] then
  366.                 cx = self.x+i
  367.                 if btxt~="" then
  368.                     self.t.setCursorPos(cx+self.pY-1,self.y+(self.pY-1))
  369.                     self.t.blit(btxt,btxtCol,bbackCol)
  370.                     btxt,btxtCol,bbackCol = "","",""
  371.                 end
  372.             else
  373.                 btxt=btxt..txt:sub(i,i)
  374.                 btxtCol = btxtCol..txtCol:sub(i,i)
  375.                 bbackCol = bbackCol..backCol:sub(i,i)
  376.             end
  377.         end
  378.         self.t.setCursorPos(cx+self.pY-2,self.y+(self.pY-1))
  379.         self.t.blit(btxt,btxtCol,bbackCol)
  380.     end
  381.     function self.bufferblit(x,y)  -- NOTE: Code normal buffer system firs
  382.         game.l"bblit"
  383.         --[[clear the screen
  384.         --for i=1,table.maxn(self) do
  385.             ----------game.l("writy "..i+self.pY)-----------------------
  386.             self.t.clearLine(i+self.pY-1)
  387.         end]]
  388.         x,y=x or self.lastX, y or self.lastY
  389.         self.lastX,self.lastY = x,y
  390.         --x,y=x-1,y-1
  391.         -------game.l("blitx "..x.." y "..y)--------------------
  392.         if self.lazy then
  393.             --group operations by opnum
  394.             game.l"dsgfhjklsklghdsjklghsdjklghsdfjklgdhgjklsdhgfjkldhgjkldfhgsdfjkghsdfjkghdfsjklghsdjkigfhdgjkhg"
  395.             local ops = {}
  396.             local where = {}
  397.             for i=1,table.maxn(self) do
  398.                 ops[i] = op[i] or {}
  399.                 where[i]=where[i] or {}
  400.                 if self[i] then
  401.                     for o=1,table.maxn(self[i]) do
  402.                         if #ops[i] == 1 then
  403.                             ops[i][1] = self[i][o].opN
  404.                             where[i][1] = o
  405.                         else
  406.                             for p=1,#ops[i] do
  407.                                 if ops[i][p] > self[i][o].opN then
  408.                                     table.insert(ops[i],p,self[i][o].opN)
  409.                                     table.insert(where[i],p,o)
  410.                                 end
  411.                             end
  412.                         end
  413.                     end
  414.                 end
  415.             end
  416.             for i=1,#ops do
  417.                 for o=1,#ops[i] do
  418.                     term.setBackgroundColor(self[i][where.o].bg)
  419.                     term.setTextColor(self[i][where.o].tc)
  420.                     self.t.write(self[i][where.o].txt)
  421.                 end
  422.             end
  423.         else
  424.             --[[for i=1,table.maxn(self) do --redo, and go over the screen parts rendering to rather than entire buffer.
  425.                 if self[i] then
  426.                     --local yta = ""--------------------
  427.                     for o=1,table.maxn(self[i]) do
  428.                         --game.l("m Y "..i.." x "..o)-----------------------------------------------------
  429.                         if self[i][o] and (not (self.nr[i] or {})[o]) then
  430.                             self.t.setCursorPos(o+x,i+y)
  431.                             self.t.setBackgroundColor(self[i][o].bg)
  432.                             self.t.setTextColor(self[i][o].tc)
  433.                             self.t.write(self[i][o].txt)
  434.                             --yta=yta..self[i][o].txt ----------------------
  435.                             --game.l("ye Y "..i.." x "..o)-----------------------------------------------------
  436.                         end
  437.                     end
  438.                     --game.l(yta)-----------------------
  439.                 end
  440.             end ]]
  441.             --Construct string for text, text colors, and background colors
  442.             local tx,ty = term.getSize()
  443.             for Y=1+y,ty+y do
  444.                 local ry = Y-y
  445.                 --[[if self[ry] then
  446.                     local txt,tColor,bColor = "","",""
  447.                     local px =1
  448.                     for X=1+x,tx+x do
  449.                         local rx = X-x
  450.                         if (self.nr[ry] or {})[rx] then
  451.                             if txt~="" then
  452.                                 game.l"entr"
  453.                                 self.t.setCursorPos(px,y)
  454.                                 self.t.blit(txt,tColor,bColor)
  455.                                 --sleep(1)
  456.                                 txt,tColor,bColor = "","",""
  457.                             end
  458.                             px=rx+1
  459.                         else
  460.                             if self[ry][rx] then
  461.                                 txt = txt..self[ry][rx].txt --Add this peice of text (ex. "x") to the line txt, same for text/background colors. In a y:x table
  462.                                 tColor = tColor..(clrLk[self[ry][rx].tc] or "0")
  463.                                 bColor = bColor..(clrLk[self[ry][rx].bg] or "f")
  464.                             else
  465.                                 txt=txt.." "
  466.                                 tColor=tColor..clrLk[self.tc]
  467.                                 bColor=bColor..clrLk[self.bg]
  468.                             end
  469.                         end  
  470.                     end    
  471.                     self.t.setCursorPos(px,Y)
  472.                     --game.l("t "..tostring(txt).." co "..tostring(tColor).." bCo "..tostring(bColor))
  473.                     self.t.blit(txt,tColor,bColor)
  474.  
  475.                 end ]]
  476.             refreshY(ry,Y,x,y)
  477.                
  478.             end
  479.                        
  480.                                    
  481.         end
  482.     end
  483.     function self.clear()
  484.         local oldx,oldy = self.x,self.y
  485.         for i=1,self.sizey do --table.maxn(self) do
  486.             self.setCursorPos(1,i)
  487.             self.clearLine()
  488.         end
  489.         self.setCursorPos(oldx,oldy)
  490.     end
  491.     function self.clearLine()
  492.         local str = ""
  493.         for i=1,self.getSize() do
  494.             str=str.." "
  495.         end
  496.         local oldX = self.x
  497.         self.setCursorPos(1,self.y)
  498.         self.write(str)
  499.         self.setCursorPos(oldX,self.y)
  500.     end
  501.    local buffer=self
  502.    --buffer vars
  503.    self.opCount = 1
  504.    self.cursorBlink = true
  505.    --set bg colors
  506.  
  507.    self.bg = colors.black
  508.    self.tc = colors.white
  509.    self.t = nativeT
  510.    self.y = 1
  511.    self.x = 1
  512.    self.pY = 0
  513.    self.pX = 1
  514.    self.lastX = 1
  515.    self.lastY= 1
  516.    self.lazy = lazy
  517.    self.isntNative = true
  518.    self.resize(w,h)
  519.    self.nr = {} -- Nozone, in a y:x table. To remove, use an aerosol can.
  520.    return self--,"Thank you, come again!"
  521. end
Advertisement
Add Comment
Please, Sign In to add comment