CrazedProgrammer

Surface API 1.3

Apr 16th, 2015
365
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. -- Surface API version 1.3 by CrazedProgrammer
  2. -- You can find info and documentation on these pages:
  3. -- http://www.computercraft.info/forums2/index.php?/topic/22397-surface-api/
  4. -- You may use this in your ComputerCraft programs and modify it without asking.
  5. -- However, you may not publish this API under your name without asking me.
  6. -- If you have any suggestions, bug reports or questions then please send an email to:
  7. -- crazedprogrammer@gmail.com
  8.  
  9. local _log = math.log(2)
  10.  
  11. function create(width, height, char, backcolor, textcolor)
  12.   local surf = { }
  13.   surf.width = width
  14.   surf.height = height
  15.   surf.x1 = 1
  16.   surf.y1 = 1
  17.   surf.x2 = width
  18.   surf.y2 = height
  19.   surf.overwrite = false
  20.   surf.buffer = { }
  21.   surf.setBounds = setBounds
  22.   surf.save = save
  23.   surf.saveString = saveString
  24.   surf.render = render
  25.   surf.clear = clear
  26.   surf.drawPixel = drawPixel
  27.   surf.getPixel = getPixel
  28.   surf.drawText = drawText
  29.   surf.drawLine = drawLine
  30.   surf.drawLines = drawLines
  31.   surf.drawRect = drawRect
  32.   surf.fillRect = fillRect
  33.   surf.drawTriangle = drawTriangle
  34.   surf.fillTriangle = fillTriangle
  35.   surf.drawTriangles = drawTriangles
  36.   surf.fillTriangles = fillTriangles
  37.   surf.drawEllipse = drawEllipse
  38.   surf.fillEllipse = fillEllipse
  39.   surf.floodFill = floodFill
  40.   surf.drawSurface = drawSurface
  41.   surf.drawSurfacePart = drawSurfacePart
  42.   surf.drawSurfaceScaled = drawSurfaceScaled
  43.   surf.drawSurfaceRotated = drawSurfaceRotated
  44.   for i=1,width*height,1 do
  45.     surf.buffer[(i - 1) * 3 + 1] = char
  46.     surf.buffer[(i - 1) * 3 + 2] = backcolor
  47.     surf.buffer[(i - 1) * 3 + 3] = textcolor
  48.   end
  49.   return surf
  50. end
  51.  
  52. function load(path)
  53.   local lines = { }
  54.   local f = fs.open(path, "r")
  55.   local line = f.readLine()
  56.   while line do
  57.     table.insert(lines, line)
  58.     line = f.readLine()
  59.   end
  60.   f.close()
  61.   local height = #lines
  62.   if lines[1]:byte(1) == 30 then
  63.     local width = 0
  64.     local i = 1
  65.     while i <= #lines[1] do
  66.       local char = lines[1]:byte(i)
  67.       if char == 30 or char == 31 then
  68.         i = i + 1
  69.       else
  70.         width = width + 1
  71.       end
  72.       i = i + 1
  73.     end
  74.     local surf = surface.create(width, height)
  75.     local backcolor = nil
  76.     local testcolor = nil
  77.     for j=1,height,1 do
  78.       local i = 1
  79.       local px = 1
  80.       while i <= #lines[j] do
  81.         local char = lines[j]:byte(i)
  82.         if char == 30 then
  83.           i = i + 1
  84.           char = lines[j]:byte(i)
  85.           local color = tonumber(lines[j]:sub(i, i), 16)
  86.           if color then
  87.             backcolor = 2^color
  88.           else
  89.             backcolor = nil
  90.           end
  91.         elseif char == 31 then
  92.           i = i + 1
  93.           char = lines[j]:byte(i)
  94.           local color = tonumber(lines[j]:sub(i, i), 16)
  95.           if color then
  96.             textcolor = 2^color
  97.           else
  98.             textcolor = nil
  99.           end
  100.         else
  101.           surf.buffer[((j - 1) * surf.width + px - 1) * 3 + 1] = lines[j]:sub(i, i)
  102.           surf.buffer[((j - 1) * surf.width + px - 1) * 3 + 2] = backcolor
  103.           surf.buffer[((j - 1) * surf.width + px - 1) * 3 + 3] = textcolor
  104.           px = px + 1
  105.         end
  106.         i = i + 1
  107.       end
  108.     end
  109.     return surf
  110.   elseif lines[1]:byte(1) == 95 then
  111.     local width = tonumber(lines[1]:sub(2, 5), 16)
  112.     local height = tonumber(lines[1]:sub(6, 9), 16)
  113.     local surf = surface.create(width, height)
  114.     local n = 10
  115.     for j=1,height,1 do
  116.       for i=1,width,1 do
  117.         local char
  118.         local backcolor
  119.         local textcolor
  120.         if lines[1]:byte(n) ~= 95 then
  121.           char = string.char(tonumber(lines[1]:sub(n, n + 1), 16))
  122.         end
  123.         if lines[1]:byte(n + 2) ~= 95 then
  124.           backcolor = 2 ^ tonumber(lines[1]:sub(n + 2, n + 2), 16)
  125.         end
  126.         if lines[1]:byte(n + 3) ~= 95 then
  127.           textcolor = 2 ^ tonumber(lines[1]:sub(n + 3, n + 3), 16)
  128.         end
  129.         surf:drawPixel(i, j, char, backcolor, textcolor)
  130.         n = n + 4
  131.       end
  132.     end
  133.     return surf
  134.   else
  135.     local width = #lines[1]
  136.     local surf = surface.create(width, height)
  137.     for j=1,height,1 do
  138.       for i=1,width,1 do
  139.         local color = tonumber(lines[j]:sub(i, i), 16)
  140.         if color then
  141.           surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] = 2 ^ color
  142.         end
  143.       end
  144.     end
  145.     return surf
  146.   end
  147. end
  148.  
  149. function loadString(str)
  150.   local width = tonumber(str:sub(2, 5), 16)
  151.   local height = tonumber(str:sub(6, 9), 16)
  152.   local surf = surface.create(width, height)
  153.   local n = 10
  154.   for j=1,height,1 do
  155.     for i=1,width,1 do
  156.       local char, backcolor, textcolor
  157.       if str:byte(n) ~= 95 then
  158.         char = string.char(tonumber(str:sub(n, n + 1), 16))
  159.       end
  160.       if str:byte(n + 2) ~= 95 then
  161.         backcolor = 2 ^ tonumber(str:sub(n + 2, n + 2), 16)
  162.       end
  163.       if str:byte(n + 3) ~= 95 then
  164.         textcolor = 2 ^ tonumber(str:sub(n + 3, n + 3), 16)
  165.       end
  166.       surf:drawPixel(i, j, char, backcolor, textcolor)
  167.       n = n + 4
  168.     end
  169.   end
  170.   return surf
  171. end
  172.  
  173. function setBounds(surf, x1, y1, x2, y2)
  174.   if x2 < x1 then
  175.     local temp = x1
  176.     x1 = x2
  177.     x2 = temp
  178.   end
  179.   if y2 < y1 then
  180.     local temp = y1
  181.     y1 = y2
  182.     y2 = temp
  183.   end
  184.   if x2 < 1 then return end
  185.   if x1 > surf.width then return end
  186.   if y2 < 1 then return end
  187.   if y1 > surf.height then return end
  188.   if x1 < 1 then x1 = 1 end
  189.   if x2 > surf.width then x2 = surf.width end
  190.   if y1 < 1 then y1 = 1 end
  191.   if y2 > surf.height then y2 = surf.height end
  192.   surf.x1 = x1
  193.   surf.y1 = y1
  194.   surf.x2 = x2
  195.   surf.y2 = y2
  196. end
  197.  
  198. function save(surf, path, type)
  199.   type = type or "srf"
  200.   local f = fs.open(path, "w")
  201.   if type == "nfp" then
  202.     for j=1,surf.height,1 do
  203.       if j > 1 then f.write("\n") end
  204.       for i=1,surf.width,1 do
  205.         f.write(_colorToHex(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]))
  206.       end
  207.     end
  208.   elseif type == "nft" then
  209.     for j=1,surf.height,1 do
  210.       backcolor = -1
  211.       textcolor = -1
  212.       if j > 1 then f.write("\n") end
  213.       for i=1,surf.width,1 do
  214.         if backcolor ~= surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] then
  215.           f.write(string.char(30))
  216.           backcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]
  217.           f.write(_colorToHex(backcolor))
  218.         end
  219.         if textcolor ~= surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] then
  220.           f.write(string.char(31))
  221.           textcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3]
  222.           f.write(_colorToHex(textcolor))
  223.         end
  224.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] then
  225.           f.write(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1])
  226.         else
  227.           f.write(" ")
  228.         end
  229.       end
  230.     end
  231.   elseif type == "srf" then
  232.     f.write("_"..string.format("%04x", surf.width)..string.format("%04x", surf.height))
  233.     for j=1,surf.height,1 do
  234.       for i=1,surf.width,1 do
  235.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] then
  236.           f.write(string.format("%02x", surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1]:byte(1)))
  237.         else
  238.           f.write("__")
  239.         end
  240.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] then
  241.           f.write(string.format("%x", math.log(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2])/_log))
  242.         else
  243.           f.write("_")
  244.         end
  245.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] then
  246.           f.write(string.format("%x", math.log(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3])/_log))
  247.         else
  248.           f.write("_")
  249.         end
  250.       end
  251.     end
  252.   end
  253.   f.close()
  254. end
  255.  
  256. function saveString(surf)
  257.   local str = "_"..string.format("%04x", surf.width)..string.format("%04x", surf.height)
  258.   for j=1,surf.height,1 do
  259.     for i=1,surf.width,1 do
  260.       if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] then
  261.         str = str..string.format("%02x", surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1]:byte(1))
  262.       else
  263.         str = str.."__"
  264.       end
  265.       if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] then
  266.         str = str..string.format("%x", math.log(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2])/_log)
  267.       else
  268.         str = str.."_"
  269.       end
  270.       if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] then
  271.         str = str..string.format("%x", math.log(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3])/_log)
  272.       else
  273.         str = str.."_"
  274.       end
  275.     end
  276.   end
  277.   return str
  278. end
  279.  
  280. function render(surf, display, x, y, sx1, sy1, sx2, sy2)
  281.   display = display or term
  282.   x = x or 1
  283.   y = y or 1
  284.   sx1 = sx1 or 1
  285.   sy1 = sy1 or 1
  286.   sx2 = sx2 or surf.width
  287.   sy2 = sy2 or surf.height
  288.  
  289.   if sx2 < sx1 then
  290.     local temp = sx1
  291.     sx1 = sx2
  292.     sx2 = temp
  293.   end
  294.   if sy2 < sy1 then
  295.     local temp = sy1
  296.     sy1 = sy2
  297.     sy2 = temp
  298.   end
  299.   if sx2 < surf.x1 then return end
  300.   if sx1 > surf.x2 then return end
  301.   if sy2 < surf.y1 then return end
  302.   if sy1 > surf.y2 then return end
  303.   if sx1 < surf.x1 then sx1 = surf.x1 end
  304.   if sx2 > surf.x2 then sx2 = surf.x2 end
  305.   if sy1 < surf.y1 then sy1 = surf.y1 end
  306.   if sy2 > surf.y2 then sy2 = surf.y2 end
  307.  
  308.   if display.blit then
  309.     local cmd = { }
  310.     for j=sy1,sy2,1 do
  311.       local str = ""
  312.       local back = { }
  313.       local text = { }
  314.       for i=sx1,sx2,1 do
  315.         str = str..(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] or "\0")
  316.         back[#back + 1] = math.log(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] or 32768)/_log
  317.         text[#text + 1] = math.log(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] or 1)/_log
  318.       end
  319.       cmd[#cmd + 1] = y + j - sy1
  320.       cmd[#cmd + 1] = str
  321.       cmd[#cmd + 1] = string.format(string.rep("%x", #text), unpack(text))
  322.       cmd[#cmd + 1] = string.format(string.rep("%x", #back), unpack(back))
  323.     end
  324.    
  325.     local i = 1
  326.     for i=1,#cmd,4 do
  327.       display.setCursorPos(x, cmd[i])
  328.       display.blit(cmd[i + 1], cmd[i + 2], cmd[i + 3])
  329.     end
  330.   else
  331.     local cmd = { }
  332.     local str = ""
  333.     local backcolor = 0
  334.     local textcolor = 0
  335.     for j=sy1,sy2,1 do
  336.       cmd[#cmd + 1] = 1
  337.       cmd[#cmd + 1] = y + j - sy1
  338.       for i=sx1,sx2,1 do
  339.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2] ~= backcolor then
  340.           backcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 2]
  341.           if str ~= "" then
  342.             cmd[#cmd + 1] = 4
  343.             cmd[#cmd + 1] = str
  344.             str = ""
  345.           end
  346.           cmd[#cmd + 1] = 2
  347.           cmd[#cmd + 1] = backcolor
  348.         end
  349.         if surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3] ~= textcolor then
  350.           textcolor = surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 3]
  351.           if str ~= "" then
  352.             cmd[#cmd + 1] = 4
  353.             cmd[#cmd + 1] = str
  354.             str = ""
  355.           end
  356.           cmd[#cmd + 1] = 3
  357.           cmd[#cmd + 1] = textcolor
  358.         end
  359.         str = str..(surf.buffer[((j - 1) * surf.width + i - 1) * 3 + 1] or "\0")
  360.       end
  361.       cmd[#cmd + 1] = 4
  362.       cmd[#cmd + 1] = str
  363.       str = ""
  364.     end
  365.  
  366.     for i=1,#cmd/2,1 do
  367.       local c = cmd[(i - 1) * 2 + 1]
  368.       local a = cmd[(i - 1) * 2 + 2]
  369.       if c == 1 then
  370.         display.setCursorPos(x, a)
  371.       elseif c == 2 then
  372.         display.setBackgroundColor(a or 32768)
  373.       elseif c == 3 then
  374.         display.setTextColor(a or 1)
  375.       elseif c == 4 then
  376.         display.write(a)
  377.       end
  378.     end
  379.   end
  380. end
  381.  
  382. function clear(surf, char, backcolor, textcolor)
  383.   local overwrite = surf.overwrite
  384.   surf.overwrite = true
  385.   surf:fillRect(surf.x1, surf.y1, surf.x2, surf.y2, char, backcolor, textcolor)
  386.   surf.overwrite = overwrite
  387. end
  388.  
  389. function drawPixel(surf, x, y, char, backcolor, textcolor)
  390.   if x < surf.x1 or y < surf.y1 or x > surf.x2 or y > surf.y2 then return end
  391.   if char or surf.overwrite then
  392.     surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 1] = char
  393.   end
  394.   if backcolor or surf.overwrite then
  395.     surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 2] = backcolor
  396.   end
  397.   if textcolor or surf.overwrite then
  398.     surf.buffer[((y - 1) * surf.width + x - 1) * 3 + 3] = textcolor
  399.   end
  400. end
  401.  
  402. function getPixel(surf, x, y)
  403.   if x < surf.x1 or y < surf.y1 or x > surf.x2 or y > surf.y2 then return end
  404.   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]
  405. end
  406.  
  407. function drawText(surf, x, y, text, backcolor, textcolor)
  408.   local px = x
  409.   for i=1,#text,1 do
  410.     if text:sub(i, i) ~= "\n" then
  411.       surf:drawPixel(x, y, text:sub(i, i), backcolor, textcolor)
  412.     else
  413.       x = px - 1
  414.       y = y + 1
  415.     end
  416.     x = x + 1
  417.   end
  418. end
  419.  
  420. function drawLine(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  421.   local delta_x = x2 - x1
  422.   local ix = delta_x > 0 and 1 or -1
  423.   delta_x = 2 * math.abs(delta_x)
  424.   local delta_y = y2 - y1
  425.   local iy = delta_y > 0 and 1 or -1
  426.   delta_y = 2 * math.abs(delta_y)
  427.   surf:drawPixel(x1, y1, char, backcolor, textcolor)
  428.   if delta_x >= delta_y then
  429.     local error = delta_y - delta_x / 2
  430.     while x1 ~= x2 do
  431.       if (error >= 0) and ((error ~= 0) or (ix > 0)) then
  432.         error = error - delta_x
  433.         y1 = y1 + iy
  434.       end
  435.       error = error + delta_y
  436.       x1 = x1 + ix
  437.       surf:drawPixel(x1, y1, char, backcolor, textcolor)
  438.     end
  439.   else
  440.     local error = delta_x - delta_y / 2
  441.     while y1 ~= y2 do
  442.       if (error >= 0) and ((error ~= 0) or (iy > 0)) then
  443.         error = error - delta_y
  444.         x1 = x1 + ix
  445.       end
  446.       error = error + delta_x
  447.       y1 = y1 + iy
  448.       surf:drawPixel(x1, y1, char, backcolor, textcolor)
  449.     end
  450.   end
  451. end
  452.  
  453. function drawLines(surf, points, mode, char, backcolor, textcolor)
  454.   mode = mode or 1
  455.   if mode == 1 then
  456.     for i=1,#points,4 do
  457.       surf:drawLine(points[i], points[i+1], points[i+2], points[i+3], char, backcolor, textcolor)
  458.     end
  459.   elseif mode == 2 then
  460.     local lastx = points[1]
  461.     local lasty = points[2]
  462.     for i=3,#points,2 do
  463.       local curx = points[i]
  464.       local cury = points[i+1]
  465.       surf:drawLine(lastx, lasty, curx, cury, char, backcolor, textcolor)
  466.       lastx = curx
  467.       lasty = cury
  468.     end
  469.   elseif mode == 3 then
  470.     local midx = points[1]
  471.     local midy = points[2]
  472.     for i=3,#points,2 do
  473.       surf:drawLine(midx, midy, points[i], points[i+1], char, backcolor, textcolor)
  474.     end
  475.   end
  476. end
  477.  
  478. function drawRect(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  479.   surf:drawLine(x1, y1, x2, y1, char, backcolor, textcolor)
  480.   surf:drawLine(x1, y1, x1, y2, char, backcolor, textcolor)
  481.   surf:drawLine(x1, y2, x2, y2, char, backcolor, textcolor)
  482.   surf:drawLine(x2, y1, x2, y2, char, backcolor, textcolor)
  483. end
  484.  
  485. function fillRect(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  486.   if x2 < x1 then
  487.     local temp = x1
  488.     x1 = x2
  489.     x2 = temp
  490.   end
  491.   if y2 < y1 then
  492.     local temp = y1
  493.     y1 = y2
  494.     y2 = temp
  495.   end
  496.   if x2 < surf.x1 then return end
  497.   if x1 > surf.x2 then return end
  498.   if y2 < surf.y1 then return end
  499.   if y1 > surf.y2 then return end
  500.   if x1 < surf.x1 then x1 = surf.x1 end
  501.   if x2 > surf.x2 then x2 = surf.x2 end
  502.   if y1 < surf.y1 then y1 = surf.y1 end
  503.   if y2 > surf.y2 then y2 = surf.y2 end
  504.  
  505.   if char or surf.overwrite then
  506.     for y=y1,y2,1 do
  507.       for x=x1,x2,1 do
  508.         surf.buffer[((y-1) * surf.width + (x-1)) * 3 + 1] = char
  509.       end
  510.     end
  511.   end
  512.   if backcolor or surf.overwrite then
  513.     for y=y1,y2,1 do
  514.       for x=x1,x2,1 do
  515.         surf.buffer[((y-1) * surf.width + (x-1)) * 3 + 2] = backcolor
  516.       end
  517.     end
  518.   end
  519.   if textcolor or surf.overwrite then
  520.     for y=y1,y2,1 do
  521.       for x=x1,x2,1 do
  522.         surf.buffer[((y-1) * surf.width + (x-1)) * 3 + 3] = textcolor
  523.       end
  524.     end
  525.   end
  526. end
  527.  
  528. function drawTriangle(surf, x1, y1, x2, y2, x3, y3, char, backcolor, textcolor)
  529.   surf:drawLine(x1, y1, x2, y2, char, backcolor, textcolor)
  530.   surf:drawLine(x2, y2, x3, y3, char, backcolor, textcolor)
  531.   surf:drawLine(x3, y3, x1, y1, char, backcolor, textcolor)
  532. end
  533.  
  534. function fillTriangle(surf, x1, y1, x2, y2, x3, y3, char, backcolor, textcolor)
  535.   local minX = x1
  536.   local minY = y1
  537.   local maxX = x1
  538.   local maxY = y1
  539.   if x2 < minX then minX = x2 end
  540.   if x3 < minX then minX = x3 end
  541.   if y2 < minY then minY = y2 end
  542.   if y3 < minY then minY = y3 end
  543.   if x2 > maxX then maxX = x2 end
  544.   if x3 > maxX then maxX = x3 end
  545.   if y2 > maxY then maxY = y2 end
  546.   if y3 > maxY then maxY = y3 end
  547.   local width = maxX - minX + 1
  548.   local height = maxY - minY + 1
  549.   local buffer = { }
  550.   _bufferLine(buffer, width, x1 - minX + 1, y1 - minY + 1, x2 - minX + 1, y2 - minY + 1)
  551.   _bufferLine(buffer, width, x2 - minX + 1, y2 - minY + 1, x3 - minX + 1, y3 - minY + 1)
  552.   _bufferLine(buffer, width, x3 - minX + 1, y3 - minY + 1, x1 - minX + 1, y1 - minY + 1)
  553.   _bufferFill(buffer, width, height)
  554.   for i=1,width,1 do
  555.     for j=1,height,1 do
  556.       if buffer[(j - 1) * width + i] then
  557.         surf:drawPixel(minX + i - 1, minY + j - 1, char, backcolor, textcolor)
  558.       end
  559.     end
  560.   end
  561. end
  562.  
  563. function drawTriangles(surf, points, mode, char, backcolor, textcolor)
  564.   mode = mode or 1
  565.   if mode == 1 then
  566.     for i=1,#points,6 do
  567.       surf:drawTriangle(points[i], points[i+1], points[i+2], points[i+3], points[i+4], points[i+5], char, backcolor, textcolor)
  568.     end
  569.   elseif mode == 2 then
  570.     local lastx = points[1]
  571.     local lasty = points[2]
  572.     local prevx = points[3]
  573.     local prevy = points[4]
  574.     for i=5,#points,2 do
  575.       local curx = points[i]
  576.       local cury = points[i+1]
  577.       surf:drawTriangle(lastx, lasty, prevx, prevy, curx, cury, char, backcolor, textcolor)
  578.       lastx = prevx
  579.       lasty = prevy
  580.       prevx = curx
  581.       prevy = cury
  582.     end
  583.   elseif mode == 3 then
  584.     local midx = points[1]
  585.     local midy = points[2]
  586.     local lastx = points[3]
  587.     local lasty = points[4]
  588.     for i=5,#points,2 do
  589.       local curx = points[i]
  590.       local cury = points[i+1]
  591.       surf:drawTriangle(midx, midy, lastx, lasty, curx, cury, char, backcolor, textcolor)
  592.       lastx = curx
  593.       lasty = cury
  594.     end
  595.   end
  596. end
  597.  
  598. function fillTriangles(surf, points, mode, char, backcolor, textcolor)
  599.   mode = mode or 1
  600.   if mode == 1 then
  601.     for i=1,#points,6 do
  602.       surf:fillTriangle(points[i], points[i+1], points[i+2], points[i+3], points[i+4], points[i+5], char, backcolor, textcolor)
  603.     end
  604.   elseif mode == 2 then
  605.     local lastx = points[1]
  606.     local lasty = points[2]
  607.     local prevx = points[3]
  608.     local prevy = points[4]
  609.     for i=5,#points,2 do
  610.       local curx = points[i]
  611.       local cury = points[i+1]
  612.       surf:fillTriangle(lastx, lasty, prevx, prevy, curx, cury, char, backcolor, textcolor)
  613.       lastx = prevx
  614.       lasty = prevy
  615.       prevx = curx
  616.       prevy = cury
  617.     end
  618.   elseif mode == 3 then
  619.     local midx = points[1]
  620.     local midy = points[2]
  621.     local lastx = points[3]
  622.     local lasty = points[4]
  623.     for i=5,#points,2 do
  624.       local curx = points[i]
  625.       local cury = points[i+1]
  626.       surf:fillTriangle(midx, midy, lastx, lasty, curx, cury, char, backcolor, textcolor)
  627.       lastx = curx
  628.       lasty = cury
  629.     end
  630.   end
  631. end
  632.  
  633. function drawEllipse(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  634.   if x2 < x1 then
  635.     local temp = x1
  636.     x1 = x2
  637.     x2 = temp
  638.   end
  639.   if y2 < y1 then
  640.     local temp = y1
  641.     y1 = y2
  642.     y2 = temp
  643.   end
  644.   local resolution = 12
  645.   local step = (math.pi * 2) / resolution
  646.   local midX = (x1 + x2) / 2
  647.   local midY = (y1 + y2) / 2
  648.   local width = (x2 - x1) / 2
  649.   local height = (y2 - y1) / 2
  650.   local lastX = 1
  651.   local lastY = 1
  652.   for i=1,resolution+1,1 do
  653.     local x = math.floor((midX + math.cos(step * i) * width) + 0.5)
  654.     local y = math.floor((midY + math.sin(step * i) * height) + 0.5)
  655.     if i > 1 then
  656.       surf:drawLine(lastX, lastY, x, y, char, backcolor, textcolor)
  657.     end
  658.     lastX = x
  659.     lastY = y
  660.   end
  661. end
  662.  
  663. function fillEllipse(surf, x1, y1, x2, y2, char, backcolor, textcolor)
  664.   if x2 < x1 then
  665.     local temp = x1
  666.     x1 = x2
  667.     x2 = temp
  668.   end
  669.   if y2 < y1 then
  670.     local temp = y1
  671.     y1 = y2
  672.     y2 = temp
  673.   end
  674.   local resolution = 12
  675.   local step = (math.pi * 2) / resolution
  676.   local midX = (x1 + x2) / 2
  677.   local midY = (y1 + y2) / 2
  678.   local width = (x2 - x1) / 2
  679.   local height = (y2 - y1) / 2
  680.   local lastX = 1
  681.   local lastY = 1
  682.   local minX = x1
  683.   local minY = y1
  684.   local maxX = x2
  685.   local maxY = y2
  686.   local bwidth = maxX - minX + 1
  687.   local bheight = maxY - minY + 1
  688.   local buffer = { }
  689.   for i=1,resolution+1,1 do
  690.     local x = math.floor((midX + math.cos(step * i) * width) + 0.5)
  691.     local y = math.floor((midY + math.sin(step * i) * height) + 0.5)
  692.     if i > 1 then
  693.       _bufferLine(buffer, bwidth, lastX - minX + 1, lastY - minY + 1, x - minX + 1, y - minY + 1)
  694.     end
  695.     lastX = x
  696.     lastY = y
  697.   end
  698.   _bufferFill(buffer, bwidth, bheight)
  699.   for i=1,bwidth,1 do
  700.     for j=1,bheight,1 do
  701.       if buffer[(j - 1) * bwidth + i] then
  702.         surf:drawPixel(minX + i - 1, minY + j - 1, char, backcolor, textcolor)
  703.       end
  704.     end
  705.   end
  706. end
  707.  
  708. function floodFill(surf, x, y, char, backcolor, textcolor)
  709.   local stack = { x, y }
  710.   local tchar, tbackcolor, ttextcolor = surf:getPixel(x, y)
  711.   if (tchar == char) and (tbackcolor == backcolor) and (ttextcolor == textcolor) then return end
  712.   while #stack > 0 do
  713.     local cx = stack[1]
  714.     table.remove(stack, 1)
  715.     local cy = stack[1]
  716.     table.remove(stack, 1)
  717.     if not (cx < surf.x1 or cy < surf.y1 or cx > surf.x2 or cy > surf.y2) then
  718.       local cchar, cbackcolor, ctextcolor = surf:getPixel(cx, cy)
  719.       if (tchar == cchar) and (tbackcolor == cbackcolor) and (ttextcolor == ctextcolor) then
  720.         surf:drawPixel(cx, cy, char, backcolor, textcolor)
  721.         table.insert(stack, cx - 1)
  722.         table.insert(stack, cy)
  723.         table.insert(stack, cx + 1)
  724.         table.insert(stack, cy)
  725.         table.insert(stack, cx)
  726.         table.insert(stack, cy - 1)
  727.         table.insert(stack, cx)
  728.         table.insert(stack, cy + 1)
  729.       end
  730.     end
  731.   end
  732. end
  733.  
  734. function drawSurface(surf, x, y, surf2)
  735.   for j=1,surf2.height,1 do
  736.     for i=1,surf2.width,1 do
  737.       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])
  738.     end
  739.   end
  740. end
  741.  
  742. function drawSurfacePart(surf, x, y, sx1, sy1, sx2, sy2, surf2)
  743.   if sx2 < sx1 then
  744.     local temp = sx1
  745.     sx1 = sx2
  746.     sx2 = temp
  747.   end
  748.   if sy2 < sy1 then
  749.     local temp = sy1
  750.     sy1 = sy2
  751.     sy2 = temp
  752.   end
  753.   if sx2 < surf2.x1 then return end
  754.   if sx1 > surf2.x2 then return end
  755.   if sy2 < surf2.y1 then return end
  756.   if sy1 > surf2.y2 then return end
  757.   if sx1 < surf2.x1 then sx1 = surf2.x1 end
  758.   if sx2 > surf2.x2 then sx2 = surf2.x2 end
  759.   if sy1 < surf2.y1 then sy1 = surf2.y1 end
  760.   if sy2 > surf2.y2 then sy2 = surf2.y2 end
  761.  
  762.   for j=sy1,sy2,1 do
  763.     for i=sx1,sx2,1 do
  764.       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])
  765.     end
  766.   end
  767. end
  768.  
  769. function drawSurfaceScaled(surf, x1, y1, x2, y2, surf2)
  770.   local x = 0
  771.   local width = 0
  772.   local xinv = false
  773.   local y = 0
  774.   local height = 0
  775.   local yinv = false
  776.   if x2 >= x1 then
  777.     x = x1
  778.     width = x2 - x1 + 1
  779.   else
  780.     x = x2
  781.     width = x1 - x2 + 1
  782.     xinv = true
  783.   end
  784.   if y2 >= y1 then
  785.     y = y1
  786.     height = y2 - y1 + 1
  787.   else
  788.     y = y2
  789.     height = y1 - y2 + 1
  790.     yinv = true
  791.   end
  792.   local xscale = width / surf2.width
  793.   local yscale = height / surf2.height
  794.  
  795.   for j=1,height,1 do
  796.     for i=1,width,1 do
  797.       local ii = i
  798.       local jj = j
  799.       if xinv then ii = width - ii + 1 end
  800.       if yinv then jj = height - jj + 1 end
  801.       local px = math.floor((ii - 0.5) / xscale) + 1
  802.       local py = math.floor((jj - 0.5) / yscale) + 1
  803.       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])
  804.     end
  805.   end
  806. end
  807.  
  808. function drawSurfaceRotated(surf, x, y, ox, oy, angle, surf2)
  809.   local cos = math.cos(angle)
  810.   local sin = math.sin(angle)
  811.   x = x - math.floor(cos * (ox - 1) + sin * (oy - 1) + 0.5)
  812.   y = y - math.floor(cos * (oy - 1) - sin * (ox - 1) + 0.5)
  813.   local range = math.floor(math.sqrt(surf2.width * surf2.width + surf2.height * surf2.height))
  814.   for j=-range,range,1 do
  815.     for i=-range,range,1 do
  816.       local sx = math.floor(i * cos - j * sin)
  817.       local sy = math.floor(i * sin + j * cos)
  818.       if sx >= 0 and sx < surf2.width and sy >= 0 and sy < surf2.height then
  819.         surf:drawPixel(x + i, y + j, surf2.buffer[(sy * surf2.width + sx) * 3 + 1], surf2.buffer[(sy * surf2.width + sx) * 3 + 2], surf2.buffer[(sy * surf2.width + sx) * 3 + 3])
  820.       end
  821.     end
  822.   end
  823. end
  824.  
  825. function _colorToHex(color)
  826.   if color then
  827.     return string.format("%x", math.log(color)/_log)
  828.   else
  829.     return " "
  830.   end
  831. end
  832.  
  833. function _bufferLine(buffer, width, x1, y1, x2, y2)
  834.   local delta_x = x2 - x1
  835.   local ix = delta_x > 0 and 1 or -1
  836.   delta_x = 2 * math.abs(delta_x)
  837.   local delta_y = y2 - y1
  838.   local iy = delta_y > 0 and 1 or -1
  839.   delta_y = 2 * math.abs(delta_y)
  840.   buffer[(y1 - 1) * width + x1] = true
  841.   if delta_x >= delta_y then
  842.     local error = delta_y - delta_x / 2
  843.     while x1 ~= x2 do
  844.       if (error >= 0) and ((error ~= 0) or (ix > 0)) then
  845.         error = error - delta_x
  846.         y1 = y1 + iy
  847.       end
  848.       error = error + delta_y
  849.       x1 = x1 + ix
  850.       buffer[(y1 - 1) * width + x1] = true
  851.     end
  852.   else
  853.     local error = delta_x - delta_y / 2
  854.     while y1 ~= y2 do
  855.       if (error >= 0) and ((error ~= 0) or (iy > 0)) then
  856.         error = error - delta_y
  857.         x1 = x1 + ix
  858.       end
  859.       error = error + delta_x
  860.       y1 = y1 + iy
  861.       buffer[(y1 - 1) * width + x1] = true
  862.     end
  863.   end
  864. end
  865.  
  866. function _bufferFill(buffer, width, height)
  867.   for j=1,height,1 do
  868.     local lines = 0
  869.     local wait = false
  870.     for i=1,width,1 do
  871.       local cur = buffer[(j - 1) * width + i]
  872.       if cur and not wait then
  873.         lines = lines + 1
  874.         wait = true
  875.       end
  876.       if not cur and wait then
  877.         wait = false
  878.       end
  879.     end
  880.     if lines > 1 then
  881.       local write = false
  882.       local wait = false
  883.       for i=1,width,1 do
  884.         local cur = buffer[(j - 1) * width + i]
  885.         if cur then
  886.           wait = true
  887.         else
  888.           if wait then
  889.             wait = false
  890.             write = not write
  891.           end
  892.           if write then
  893.             cur = true
  894.           end
  895.         end
  896.         buffer[(j - 1) * width + i] = cur
  897.       end
  898.     end
  899.   end
  900. end
RAW Paste Data