SHARE
TWEET

Shatter fork

erilun06 Mar 26th, 2020 66 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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.  
  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
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top