Advertisement
erilun06

Shatter fork

Mar 26th, 2020
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.74 KB | None | 0 0
  1. --original license because im nice: https://github.com/hugeblank/Shatter/blob/master/LICENSE.txt
  2. --Do What The F*ck You Want To Public License
  3. --pastebin get p3qMdmz0 shatter
  4.  
  5. local mods = peripheral.wrap("back")
  6. -- ensure glasses are present
  7. local err, str = false, ""
  8. if not mods.canvas then
  9.     error("Shatter requires Overlay Glasses", 2)
  10. end
  11.  
  12. function addTerm(can)
  13.     -- ###TERMINAL API CODE###--
  14.  
  15.     -- colors, for reference use
  16.     local colors = {white = 0xf0f0f000, orange = 0xf2b23300, magenta = 0xe57fd800, lightBlue = 0x99b2f200, yellow = 0xdede6c00, lime = 0x7fcc1900, pink = 0xf2b2cc00, gray = 0x4c4c4c00, lightGray = 0x99999900, cyan = 0x4c99b200, purple = 0xb266e500, blue = 0x3366cc00, brown = 0x7f664c00, green = 0x57a64e00, red = 0xcc4c4c00, black = 0x19191900}
  17.  
  18.     -- colors by number
  19.     local cbn = {colors.white, colors.orange, colors.magenta, colors.lightBlue, colors.yellow, colors.lime, colors.pink, colors.gray, colors.lightGray, colors.cyan, colors.purple, colors.blue, colors.brown, colors.green, colors.red, colors.black}
  20.  
  21.     -- default term scale
  22.     local ox, oy = 6, 9
  23.  
  24.     -- default term scale
  25.     local sx, sy = 6, 9
  26.  
  27.     -- term bg and fg colors and alpha values
  28.     local bg, fg, bgbn, fgbn, fga, bga, fgabn, bgabn = colors.black, colors.white, 2^(#cbn-1), 2^0, 255, 255, 1, 1
  29.  
  30.     -- cursor, pos, and blink
  31.     local csr, cx, cy, cb = nil, 1, 1, true
  32.  
  33.     -- handler activity, used to ensure cursor is activated before the term is redirected to.
  34.     local active = false
  35.  
  36.     -- term size
  37.     local tx, ty = can.getSize()
  38.     tx, ty = math.floor(tx/ox), math.floor(ty/oy)
  39.  
  40.     -- Table of functions to be outputted
  41.     local out = {}
  42.  
  43.     -- screen rendering in a table
  44.     local screen = {}
  45.  
  46.  
  47.     out.screen = screen
  48.     -- populate that table
  49.     local function tPop()
  50.         local x, y = can.getSize()
  51.         for i = 1, math.floor(x/ox) do
  52.             screen[i] = {}
  53.             for j = 1, math.floor(y/oy) do
  54.                 screen[i][j] = {bg = {}, fg = {}}
  55.             end
  56.         end
  57.     end
  58.     tPop()
  59.  
  60.     -- write text in grid fashion and add to table
  61.     local function write(x, y, char, color)
  62.         x, y = math.floor(x), math.floor(y)
  63.         if x > 0 and y > 0 and x <= tx and y <= ty then
  64.             if not screen[x][y].fg.getColor then
  65.                 screen[x][y].fg = can.addText({((x-1)*ox)+1, ((y-1)*oy)+1}, char, color, ox/sx)
  66.             else
  67.                 if screen[x][y].fg.getColor() ~= color then
  68.                     screen[x][y].fg.setColor(color)
  69.                 end
  70.                 if screen[x][y].fg.getText() ~= char then
  71.                     screen[x][y].fg.setText(char)
  72.                 end
  73.             end
  74.         end
  75.     end
  76.  
  77.     -- draw pixel in grid fashion and add to table
  78.     local function draw(x, y, color)
  79.         x, y = math.floor(x), math.floor(y)
  80.         if x > 0 and y > 0 and x <= tx and y <= ty then
  81.             if not screen[x][y].bg.getColor then
  82.                 screen[x][y].bg = can.addRectangle((x-1)*ox, (y-1)*oy, ox, oy, color)
  83.             else
  84.                 if screen[x][y].bg.getColor() ~= color then
  85.                     screen[x][y].bg.setColor(color)
  86.                 end
  87.             end
  88.         end
  89.     end
  90.  
  91.     -- get the data of a particular pixel
  92.     local function getData(pixel)
  93.         if pixel then
  94.             return {
  95.                 bgc = bit32.band(pixel.bg.getColor(), 2^32-1), -- Credit to MC:Anavrins for bit32 ingenuity
  96.                 fgc = bit32.band(pixel.fg.getColor(), 2^32-1),
  97.                 txt = pixel.fg.getText()
  98.             }
  99.         end
  100.     end
  101.  
  102.     -- set the data of a particular pixel
  103.     local function setData(pixel, data)
  104.         if pixel and data then
  105.             if pixel.bg.getPosition then
  106.                 local x, y = pixel.bg.getPosition()
  107.                 draw(math.floor(x/ox)+1, math.floor(y/oy)+1, data.bgc)
  108.                 write(math.floor(x/ox)+1, math.floor(y/oy)+1, data.txt, data.fgc)
  109.             end
  110.         end
  111.     end
  112.  
  113.     -- populate term with default bg and fg colors.
  114.     local function repopulate()
  115.         local x, y = can.getSize()
  116.         for i = 1, math.floor(x/ox) do
  117.             for j = 1, math.floor(y/oy) do
  118.                 draw(i, j, bg)
  119.             end
  120.         end
  121.         for i = 1, math.floor(x/ox) do
  122.             for j = 1, math.floor(y/oy) do
  123.                 write(i, j, "", fg)
  124.             end
  125.         end
  126.         csr = can.addText({cx*ox, (cy*oy)+1}, "", 0xffffffff, ox/sx)
  127.     end
  128.  
  129.     -- A simple error message I am too lazy to type twice
  130.     local function invCol(col)
  131.         error("invalid color (got "..col..")", 2)
  132.     end
  133.  
  134.     -- very basic implementation of base 2 logarithm
  135.     local function lb2(num)
  136.         return math.log(num)/math.log(2)
  137.     end
  138.  
  139.     -- Converts a hex value into 3 seperate r, g, and b values
  140.     local function torgba(hex)
  141.         -- Technically also gets a value, but it thrown out due to what this is needed for
  142.         -- Credit to MC:valithor2 for this algorithm
  143.         local vals = {}
  144.         for i = 1, 4 do
  145.             vals[i] = hex%256
  146.             hex = (hex-vals[i])/256
  147.         end
  148.         return vals[4]/255, vals[3]/255, vals[2]/255
  149.     end
  150.  
  151.     local function refreshColor(oc, nc)
  152.         -- refreshes terminal when palette values are manipulated
  153.         for i = 1, #screen do
  154.             for j = 1, #screen[i] do
  155.                 local op, changed = getData(screen[i][j]), false
  156.                 if op.bgc == oc then
  157.                     op.bgc = nc
  158.                     changed = true
  159.                 end
  160.                 if op.fgc == oc then
  161.                     op.fgc = nc
  162.                     changed = true
  163.                 end
  164.                 if changed then
  165.                     setData(screen[i][j], op)
  166.                 end
  167.             end
  168.         end
  169.     end
  170.  
  171.     out.write = function(str)
  172.         -- term.write
  173.         str = tostring(str)
  174.         for i = 1, #str do
  175.             write(cx+i-1, cy, str:sub(i, i), fg+fga)
  176.             draw(cx+i-1, cy, bg+bga)
  177.         end
  178.         cx = cx+#str
  179.     end
  180.  
  181.     out.blit = function(str, tfg, tbg)
  182.         -- term.blit
  183.         if type(str) ~= "string" then
  184.             error("bad argument #1 (expected string, got "..type(str)..")", 2)
  185.         elseif type(tfg) ~= "string" then
  186.             error("bad argument #2 (expected string, got "..type(tfg)..")", 2)
  187.         elseif type(tbg) ~= "string" then
  188.             error("bad argument #3 (expected string, got "..type(tbg)..")", 2)
  189.         end
  190.         for i = 1, #str do
  191.             nfg = cbn[tonumber(tfg:sub(i,i), 16)+1]
  192.             nbg = cbn[tonumber(tbg:sub(i,i), 16)+1]
  193.             draw(cx+i-1, cy, nbg+bga)
  194.             write(cx+i-1, cy, str:sub(i,i), nfg+fga)
  195.         end
  196.         cx = cx+#str
  197.     end
  198.  
  199.     out.clear = function()
  200.         -- term.clear
  201.         for i = 1, tx do
  202.             for j = 1, ty do
  203.                 write(i, j, "", fg+fga)
  204.                 draw(i, j, bg+bga)
  205.             end
  206.         end
  207.     end
  208.  
  209.     out.clearLine = function()
  210.         -- term.clearLine
  211.         if cy > 0 and cy <= ty then
  212.             for i = 1, tx do
  213.                 draw(i, cy, bg+bga)
  214.                 write(i, cy, "", fg+fga)
  215.             end
  216.         end
  217.     end
  218.  
  219.     out.getCursorPos = function()
  220.         -- term.getCursorPos
  221.         return cx, cy
  222.     end
  223.  
  224.     out.setCursorPos = function(x, y)
  225.         -- term.setCursorPos
  226.         if type(x) ~= "number" then
  227.             error("bad argument #1 (expected number, got "..type(x)..")", 2)
  228.         elseif type(y) ~= "number" then
  229.             error("bad argument #2 (expected number, got "..type(y)..")", 2)
  230.         end
  231.         csr.setPosition((x-1)*ox, ((y-1)*oy)+1)
  232.         cx, cy = x, y
  233.     end
  234.  
  235.     out.setCursorBlink = function(b)
  236.         -- term.setCursorBlink
  237.         if type(b) ~= "boolean" then
  238.             error("bad argument #1 (expected boolean, got "..type(b)..")", 2)
  239.         end
  240.         cb = b
  241.     end
  242.  
  243.     out.isColor = function()
  244.         -- term.isColor
  245.         return true, "now with more alpha!"
  246.     end
  247.  
  248.     out.getSize = function()
  249.         -- term.getSize
  250.         return tx, ty
  251.     end
  252.  
  253.     out.scroll = function(amount)
  254.         -- term.scroll
  255.         local tcx, tcy = out.getCursorPos()
  256.         if type(amount) ~= "number" then
  257.             error("bad argument #1 (expected number, got "..type(amount)..")", 2)
  258.         end
  259.         for i = 1, tx, amount^0 do
  260.             if i > 0 and i <= ty and i-amount > 0 and i-amount <= ty then
  261.                 screen[i-amount] = screen[i]
  262.             elseif not (i > 0 and i <= ty) then
  263.                 out.setCursorPos(1, i)
  264.                 out.clearLine()
  265.             end
  266.         end
  267.     end
  268.  
  269.     out.setTextColor = function(col)
  270.         -- term.setTextColor
  271.         if type(col) ~= "number" then
  272.             error("bad argument #1 (number expected, got "..type(col)..")", 2)
  273.         end
  274.         if lb2(col) > #cbn or lb2(col) ~= math.ceil(lb2(col)) then
  275.             invCol(col)
  276.         else
  277.             fg = cbn[lb2(col)+1]
  278.             fgbn = col
  279.             csr.setColor(fg+fga)
  280.         end
  281.     end
  282.  
  283.     out.setBackgroundColor = function(col)
  284.         -- term.setBackgroundColor
  285.         if type(col) ~= "number" then
  286.             error("bad argument #1 (expected number, got "..type(col)..")", 2)
  287.         end
  288.         if lb2(col) > #cbn or lb2(col) ~= math.ceil(lb2(col)) then
  289.             invCol(col)
  290.         else
  291.             bg = cbn[lb2(col)+1]
  292.             bgbn = col
  293.         end
  294.     end
  295.  
  296.     -- Text & BG Alpha innovated by MC:Ale32bit
  297.     out.setTextAlpha = function(val)
  298.         -- set the alpha value of the text
  299.         if type(val) ~= "number" then
  300.             error("bad argument #1 (expected number, got "..type(val)..")", 2)
  301.         end
  302.         if val > 1 then val = 1 elseif val < 0 then val = 0 end
  303.         fga = math.floor(val*255)
  304.         fgabn = val
  305.         csr.setAlpha(fga)
  306.     end
  307.  
  308.     out.setBackgroundAlpha = function(val)
  309.         -- set the alpha value of the background
  310.         if type(val) ~= "number" then
  311.             error("bad argument #1 (expected number, got "..type(val)..")", 2)
  312.         end
  313.         if val > 1 then val = 1 elseif val < 0 then val = 0 end
  314.         bga = math.floor(val*255)
  315.         bgabn = val
  316.     end
  317.  
  318.     out.setTextHex = function(hex)
  319.         -- set the hex color value of the text
  320.         if type(tonumber(hex, 16)) ~= "number" then
  321.             error("bad argument #1 (expected number, got "..type(hex)..")", 2)
  322.         end
  323.         fg = hex*0x100
  324.         fgbn = 1
  325.         csr.setColor(fg+fga)
  326.     end
  327.  
  328.     out.setBackgroundHex = function(hex)
  329.         -- set the hex color value of the background
  330.         if type(tonumber(hex, 16)) ~= "number" then
  331.             error("bad argument #1 (expected number, got "..type(hex)..")", 2)
  332.         end
  333.         bg = hex*0x100
  334.         bgbn = 1
  335.     end
  336.  
  337.     out.getTextColor = function()
  338.         -- term.getTextColor
  339.         return fgbn
  340.     end
  341.  
  342.     out.getBackgroundColor = function()
  343.         -- term.getBackgroundColor
  344.         return bgbn
  345.     end
  346.  
  347.     out.getTextAlpha = function()
  348.         -- get the alpha value of the text
  349.         return fgabn
  350.     end
  351.  
  352.     out.getBackgroundAlpha = function()
  353.         -- get the alpha value of the background
  354.         return bgabn
  355.     end
  356.  
  357.     out.getTextHex = function()
  358.         -- get the hex color value of the text
  359.         return fg
  360.     end
  361.  
  362.     out.getBackgroundHex = function()
  363.         -- get the hex color value of the background
  364.         return bg
  365.     end
  366.  
  367.     out.getPaletteColor = function(col)
  368.         -- term.getPaletteColor
  369.         if type(col) ~= "number" then
  370.             error("bad argument #1 (number expected, got "..type(col)..")", 2)
  371.         end
  372.         if lb2(col) > #cbn or lb2(col) ~= math.ceil(lb2(col)) then
  373.             invCol(col)
  374.         end
  375.         return torgba(cbn[lb2(col)+1])
  376.     end
  377.  
  378.     out.setPaletteColor = function(cnum, r, g, b)
  379.         -- term.setPaletteColor
  380.         local oc = cbn[lb2(cnum)+1]
  381.         if type(cnum) ~= "number" then
  382.             error("bad argument #1 (number expected, got "..type(cnum)..")", 2)
  383.         end
  384.         if type(r) ~= "number" then
  385.             error("bad argument #2 (number expected, got "..type(r)..")", 2)
  386.         end
  387.         if g then
  388.             if type(g) ~= "number" then
  389.                 error("bad argument #3 (number expected, got "..type(g)..")", 2)
  390.             elseif type(b) ~= "number" then
  391.                 error("bad argument #4 (number expected, got "..type(b)..")", 2)
  392.             end
  393.             if r > 1 then r = 1 elseif r < 0 then r = 0 end
  394.             if g > 1 then g = 1 elseif g < 0 then g = 0 end
  395.             if b > 1 then b = 1 elseif b < 0 then b = 0 end
  396.             cbn[lb2(cnum)+1] = (((r*255)*(16^6))+((g*255)*(16^4))+((b*255)*(16^2)))
  397.         else
  398.             cbn[lb2(cnum)+1] = (r*256)
  399.         end
  400.         if bgbn == cnum then
  401.             out.setBackgroundColor(bgbn)
  402.         end
  403.         if fgbn == cnum then
  404.             out.setTextColor(fgbn)
  405.         end
  406.         refreshColor(oc, cbn[lb2(cnum)+1])
  407.     end
  408.  
  409.     out.setTextScale = function(scale)
  410.         if type(scale) ~= "number" then
  411.             error("bad argument #1 (number expected, got "..type(scale)..")", 2)
  412.         end
  413.         if 0.4 >= scale or scale > 10 then
  414.             error("Expected number in range 0.5-10", 2)
  415.         end
  416.         ox, oy = math.ceil(scale*sx), math.ceil(scale*sy)
  417.         tx, ty = can.getSize()
  418.         tx, ty = math.floor(tx/ox), math.floor(ty/oy)
  419.         csr.remove()
  420.         local oldscr = screen -- replicate the screen
  421.         screen = {} -- remove it for repopulation of table w/ new scale
  422.         tPop() -- repopulate table
  423.         repopulate() -- add objects
  424.         for i = 1, #oldscr do -- rerender screen in new scale
  425.             for j = 1, #oldscr[i] do
  426.                 if oldscr[i][j].bg.getColor ~= nil then
  427.                     if screen[i] and screen[i][j] then
  428.                         setData(screen[i][j], getData(oldscr[i][j]))
  429.                     end
  430.                     oldscr[i][j].bg.remove()
  431.                     oldscr[i][j].fg.remove()
  432.                 end
  433.             end
  434.         end
  435.         os.queueEvent("shatter_resize")
  436.     end
  437.  
  438.     -- compat for all those UK'ers
  439.     out.isColour = out.isColor
  440.     out.setTextColour = out.setTextColor
  441.     out.setBackgroundColour = out.setBackgroundColor
  442.     out.setPaletteColour = out.setPaletteColor
  443.     out.getTextColour = out.getTextColor
  444.     out.getBackgroundColour = out.getBackgroundColor
  445.     out.getPaletteColour = out.getPaletteColor
  446.  
  447.     -- ###TERMINAL CREATION CODE###--
  448.     repopulate()
  449.     local coro = function()
  450.         parallel.waitForAll(function()
  451.             -- cursor flicker
  452.             while true do
  453.                 if not cb then
  454.                     csr.setText(" ")
  455.                     sleep()
  456.                 else
  457.                     csr.setText("_")
  458.                     sleep(.4)
  459.                     csr.setText(" ")
  460.                     sleep(.4)
  461.                 end
  462.             end
  463.         end,
  464.         function()
  465.             -- glasses event handler conversion
  466.             while true do
  467.                 local e = {os.pullEvent()}
  468.                 if e[1]:find("glasses") then
  469.                     local _, b = e[1]:find("glasses")
  470.                     e[1], e[3], e[4] = "mouse"..e[1]:sub(b+1, -1), math.ceil(e[3]/ox), math.ceil(e[4]/oy)
  471.                     os.queueEvent(unpack(e))
  472.                 end
  473.             end
  474.         end)
  475.     end
  476.  
  477.     return out, coro
  478. end
  479.  
  480. return addTerm
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement