Advertisement
CrazedProgrammer

Surface API 1.0

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