Advertisement
CrazedProgrammer

Surface API 1.0

Mar 16th, 2015
449
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 11.53 KB | None | 0 0
  1. -- Surface API version 1.0 by CrazedProgrammer
  2. -- You may use this in your ComputerCraft programs and modify it without asking.
  3. -- However, you may not publish this API under your name without asking me.
  4. -- If you have any suggestions, bug reports or questions then please send an email to:
  5. -- crazedprogrammer@gmail.com
  6.  
  7. function create(width, height, char, backcolor, textcolor)
  8.   local surf = { }
  9.   surf.width = width
  10.   surf.height = height
  11.   surf.overwrite = false
  12.   surf.buffer = { }
  13.   surf.save = save
  14.   surf.drawToDisplay = drawToDisplay
  15.   surf.clear = clear
  16.   surf.drawPixel = drawPixel
  17.   surf.getPixel = getPixel
  18.   surf.drawText = drawText
  19.   surf.drawLine = drawLine
  20.   surf.drawRect = drawRect
  21.   surf.fillRect = fillRect
  22.   surf.drawSurface = drawSurface
  23.   surf.drawSurfacePart = drawSurfacePart
  24.   surf.drawSurfaceScaled = drawSurfaceScaled
  25.   for i=1,width*height,1 do
  26.     surf.buffer[(i - 1) * 3 + 1] = char
  27.     surf.buffer[(i - 1) * 3 + 2] = backcolor
  28.     surf.buffer[(i - 1) * 3 + 3] = textcolor
  29.   end
  30.   return surf
  31. end
  32.  
  33. function load(path)
  34.   local lines = { }
  35.   local f = fs.open(path, "r")
  36.   local line = f.readLine()
  37.   while line do
  38.     table.insert(lines, line)
  39.     line = f.readLine()
  40.   end
  41.   f.close()
  42.   local height = #lines
  43.   if lines[1]:byte(1) == 30 then
  44.     local width = 0
  45.     local i = 1
  46.     while i <= #lines[1] do
  47.       local char = lines[1]:byte(i)
  48.       if char == 30 or char == 31 then
  49.         i = i + 1
  50.       else
  51.         width = width + 1
  52.       end
  53.       i = i + 1
  54.     end
  55.     local surf = surface.create(width, height)
  56.     local backcolor = nil
  57.     local testcolor = nil
  58.     for j=1,height,1 do
  59.       local i = 1
  60.       local px = 1
  61.       while i <= #lines[j] do
  62.         local char = lines[j]:byte(i)
  63.         if char == 30 then
  64.           i = i + 1
  65.           char = lines[j]:byte(i)
  66.           local color = tonumber(lines[j]:sub(i, i), 16)
  67.           if color then
  68.             backcolor = 2^color
  69.           else
  70.             backcolor = nil
  71.           end
  72.         elseif char == 31 then
  73.           i = i + 1
  74.           char = lines[j]:byte(i)
  75.           local color = tonumber(lines[j]:sub(i, i), 16)
  76.           if color then
  77.             textcolor = 2^color
  78.           else
  79.             textcolor = nil
  80.           end
  81.         else
  82.           surf.buffer[((j - 1) * surf.width + px - 1) * 3 + 1] = lines[j]:sub(i, i)
  83.           surf.buffer[((j - 1) * surf.width + px - 1) * 3 + 2] = backcolor
  84.           surf.buffer[((j - 1) * surf.width + px - 1) * 3 + 3] = textcolor
  85.           px = px + 1
  86.         end
  87.         i = i + 1
  88.       end
  89.     end
  90.     return surf
  91.   else
  92.     local width = #lines[1]
  93.     local surf = surface.create(width, height)
  94.     for j=1,height,1 do
  95.       for i=1,width,1 do
  96.         local color = tonumber(lines[j]:sub(i, i), 16)
  97.         if color then
  98.           surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] = 2 ^ color
  99.         end
  100.       end
  101.     end
  102.     return surf
  103.   end
  104. end
  105.  
  106. function _colorToHex(color)
  107.   if color then
  108.     return string.format("%x", math.log(color)/math.log(2))
  109.   else
  110.     return " "
  111.   end
  112. end
  113.  
  114. function save(surf, path, type)
  115.   type = type or "nft"
  116.   local f = fs.open(path, "w")
  117.   if type == "nfp" then
  118.     for j=1,surf.height,1 do
  119.       if j > 1 then f.write("\n") end
  120.       for i=1,surf.width,1 do
  121.         f.write(colorToHex(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]))
  122.       end
  123.     end
  124.   elseif type == "nft" then
  125.     for j=1,surf.height,1 do
  126.       backcolor = -1
  127.       textcolor = -1
  128.       if j > 1 then f.write("\n") end
  129.       for i=1,surf.width,1 do
  130.         if backcolor ~= surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] then
  131.           f.write(string.char(30))
  132.           backcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]
  133.           f.write(_colorToHex(backcolor))
  134.         end
  135.         if textcolor ~= surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] then
  136.           f.write(string.char(31))
  137.           textcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3]
  138.           f.write(_colorToHex(textcolor))
  139.         end
  140.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] then
  141.           f.write(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1])
  142.         else
  143.           f.write(" ")
  144.         end
  145.       end
  146.     end
  147.   end
  148.   f.close()
  149. end
  150.  
  151. function drawToDisplay(surf, display, x, y, sx1, sy1, sx2, sy2)
  152.   x = x or 1
  153.   y = y or 1
  154.   sx1 = sx1 or 1
  155.   sy1 = sy1 or 1
  156.   sx2 = sx2 or surf.width
  157.   sy2 = sy2 or surf.height
  158.   local cmd = { }
  159.   local str = ""
  160.   local backcolor = 0
  161.   local textcolor = 0
  162.  
  163.   for j=sy1,sy2,1 do
  164.     cmd[#cmd + 1] = 1
  165.     cmd[#cmd + 1] = y + j - sy1
  166.     for i=sx1,sx2,1 do
  167.       if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] ~= backcolor then
  168.         backcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]
  169.         if str ~= "" then
  170.           cmd[#cmd + 1] = 4
  171.           cmd[#cmd + 1] = str
  172.           str = ""
  173.         end
  174.         cmd[#cmd + 1] = 2
  175.         cmd[#cmd + 1] = backcolor
  176.       end
  177.       if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] ~= textcolor then
  178.         textcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3]
  179.         if str ~= "" then
  180.           cmd[#cmd + 1] = 4
  181.           cmd[#cmd + 1] = str
  182.           str = ""
  183.         end
  184.         cmd[#cmd + 1] = 3
  185.         cmd[#cmd + 1] = textcolor
  186.       end
  187.       str = str..surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1]
  188.     end
  189.     cmd[#cmd + 1] = 4
  190.     cmd[#cmd + 1] = str
  191.     str = ""
  192.   end
  193.  
  194.   for i=1,#cmd/2,1 do
  195.     local c = cmd[(i - 1) * 2 + 1]
  196.     local a = cmd[(i - 1) * 2 + 2]
  197.     if c == 1 then
  198.       display.setCursorPos(x, a)
  199.     elseif c == 2 then
  200.       display.setBackgroundColor(a)
  201.     elseif c == 3 then
  202.       display.setTextColor(a)
  203.     elseif c == 4 then
  204.       display.write(a)
  205.     end
  206.   end
  207. end
  208.  
  209. function clear(surf, char, backcolor, textcolor)
  210.   for i=1,surf.width*surf.height,1 do
  211.     surf.buffer[(i - 1) * 3 + 1] = char
  212.     surf.buffer[(i - 1) * 3 + 2] = backcolor
  213.     surf.buffer[(i - 1) * 3 + 3] = textcolor
  214.   end
  215. end
  216.  
  217. function drawPixel(surf, x, y, char, backcolor, textcolor)
  218.   if x < 1 or y < 1 or x > surf.width or y > surf.height then return end
  219.   if char or surf.overwrite then
  220.     surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 1] = char
  221.   end
  222.   if backcolor or surf.overwrite then
  223.     surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 2] = backcolor
  224.   end
  225.   if textcolor or surf.overwrite then
  226.     surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 3] = textcolor
  227.   end
  228. end
  229.  
  230. function getPixel(surf, x, y)
  231.   if x < 1 then return end
  232.   if x > surf.width then return end
  233.   if y < 1 then return end
  234.   if y > surf.height then return end
  235.   return surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 1], surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 2], surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 3]
  236. end
  237.  
  238. function drawText(surf, x, y, text, backcolor, textcolor)
  239.   local px = x
  240.   for i=1,#text,1 do
  241.     if text:sub(i, i) ~= "\n" then
  242.       surf:drawPixel(x, y, text:sub(i, i), backcolor, textcolor)
  243.     else
  244.       x = px - 1
  245.       y = y + 1
  246.     end
  247.     x = x + 1
  248.   end
  249. end
  250.  
  251. function drawLine(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  252.   local delta_x = x2 - x1
  253.   local ix = delta_x > 0 and 1 or -1
  254.   delta_x = 2 * math.abs(delta_x)
  255.   local delta_y = y2 - y1
  256.   local iy = delta_y > 0 and 1 or -1
  257.   delta_y = 2 * math.abs(delta_y)
  258.   surf:drawPixel(x1, y1, char, backcolor, textcolor)
  259.   if delta_x >= delta_y then
  260.     local error = delta_y - delta_x / 2
  261.     while x1 ~= x2 do
  262.       if (error >= 0) and ((error ~= 0) or (ix > 0)) then
  263.         error = error - delta_x
  264.         y1 = y1 + iy
  265.       end
  266.       error = error + delta_y
  267.       x1 = x1 + ix
  268.       surf:drawPixel(x1, y1, char, backcolor, textcolor)
  269.     end
  270.   else
  271.     local error = delta_x - delta_y / 2
  272.     while y1 ~= y2 do
  273.       if (error >= 0) and ((error ~= 0) or (iy > 0)) then
  274.         error = error - delta_y
  275.         x1 = x1 + ix
  276.       end
  277.       error = error + delta_x
  278.       y1 = y1 + iy
  279.       surf:drawPixel(x1, y1, char, backcolor, textcolor)
  280.     end
  281.   end
  282. end
  283.  
  284. function drawRect(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  285.   surf:drawLine(x1, y1, x2, y1, char, backcolor, textcolor)
  286.   surf:drawLine(x1, y1, x1, y2, char, backcolor, textcolor)
  287.   surf:drawLine(x1, y2, x2, y2, char, backcolor, textcolor)
  288.   surf:drawLine(x2, y1, x2, y2, char, backcolor, textcolor)
  289. end
  290.  
  291. function fillRect(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  292.   if x2 < x1 then
  293.     local temp = x1
  294.     x1 = x2
  295.     x2 = temp
  296.   end
  297.   if y2 < y1 then
  298.     local temp = y1
  299.     y1 = y2
  300.     y2 = temp
  301.   end
  302.   if x2 < 1 then return end
  303.   if x1 > surf.width then return end
  304.   if y2 < 1 then return end
  305.   if y1 > surf.width then return end
  306.   if x1 < 1 then x1 = 1 end
  307.   if x2 > surf.width then x2 = surf.width end
  308.   if y1 < 1 then y1 = 1 end
  309.   if y2 > surf.width then y2 = surf.height end
  310.  
  311.   if char or surf.overwrite then
  312.     for y=y1,y2,1 do
  313.       for x=x1,x2,1 do
  314.         surf.buffer[((y-1) * surf.width + (x-1)) * 3 + 1] = char
  315.       end
  316.     end
  317.   end
  318.   if backcolor or surf.overwrite then
  319.     for y=y1,y2,1 do
  320.       for x=x1,x2,1 do
  321.         surf.buffer[((y-1) * surf.width + (x-1)) * 3 + 2] = backcolor
  322.       end
  323.     end
  324.   end
  325.   if textcolor or surf.overwrite then
  326.     for y=y1,y2,1 do
  327.       for x=x1,x2,1 do
  328.         surf.buffer[((y-1) * surf.width + (x-1)) * 3 + 3] = textcolor
  329.       end
  330.     end
  331.   end
  332. end
  333.  
  334. function drawSurface(surf, x, y, surf2)
  335.   for j=1,surf2.height,1 do
  336.     for i=1,surf2.width,1 do
  337.       surf:drawPixel(i + x - 1, j + y - 1, surf2.buffer[((j-1) * surf2.width + (i-1)) * 3 + 1], surf2.buffer[((j-1) * surf2.width + (i-1)) * 3 + 2], surf2.buffer[((j-1) * surf2.width + (i-1)) * 3 + 3])
  338.     end
  339.   end
  340. end
  341.  
  342. function drawSurfacePart(surf, x, y, sx1, sy1, sx2, sy2, surf2)
  343.   if sx2 < sx1 then
  344.     local temp = sx1
  345.     sx1 = sx2
  346.     sx2 = temp
  347.   end
  348.   if sy2 < sy1 then
  349.     local temp = sy1
  350.     sy1 = sy2
  351.     sy2 = temp
  352.   end
  353.   if sx2 < 1 then return end
  354.   if sx1 > surface.width then return end
  355.   if sy2 < 1 then return end
  356.   if sy1 > surface.width then return end
  357.   if sx1 < 1 then sx1 = 1 end
  358.   if sx2 > surface.width then sx2 = surface.width end
  359.   if sy1 < 1 then sy1 = 1 end
  360.   if sy2 > surface.width then sy2 = surface.height end
  361.  
  362.   for j=sy1,sy2,1 do
  363.     for i=sx1,sx2,1 do
  364.       surf:drawPixel(x + i - sx1, y + j - sy1, surf2.buffer[((j-1) * surf2.width + (i-1)) * 3 + 1], surf2.buffer[((j-1) * surf2.width + (i-1)) * 3 + 2], surf2.buffer[((j-1) * surf2.width + (i-1)) * 3 + 3])
  365.     end
  366.   end
  367. end
  368.  
  369. function drawSurfaceScaled(surf, x1, y1, x2, y2, surf2)
  370.   local x = 0
  371.   local width = 0
  372.   local xinv = false
  373.   local y = 0
  374.   local height = 0
  375.   local yinv = false
  376.   if x2 >= x1 then
  377.     x = x1
  378.     width = x2 - x1 + 1
  379.   else
  380.     x = x2
  381.     width = x1 - x2 + 1
  382.     xinv = true
  383.   end
  384.   if y2 >= y1 then
  385.     y = y1
  386.     height = y2 - y1 + 1
  387.   else
  388.     y = y2
  389.     height = y1 - y2 + 1
  390.     yinv = true
  391.   end
  392.   local xscale = width / surf2.width
  393.   local yscale = height / surf2.height
  394.  
  395.   for j=1,height,1 do
  396.     for i=1,width,1 do
  397.       local ii = i
  398.       local jj = j
  399.       if xinv then ii = width - ii + 1 end
  400.       if yinv then jj = height - jj + 1 end
  401.       local px = math.floor((ii - 0.5) / xscale) + 1
  402.       local py = math.floor((jj - 0.5) / yscale) + 1
  403.       surf:drawPixel(x + i - 1, y + j - 1, surf2.buffer[((py-1) * surf2.width + (px-1)) * 3 + 1], surf2.buffer[((py-1) * surf2.width + (px-1)) * 3 + 2], surf2.buffer[((py-1) * surf2.width + (px-1)) * 3 + 3])
  404.     end
  405.   end
  406. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement