Advertisement
CrazedProgrammer

Surface API 1.3

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