Advertisement
Stawlie0

Untitled

Oct 10th, 2023
563
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.79 KB | None | 0 0
  1. --Добавить сортировку по цветам
  2. --Переменная библиотеки
  3. local doubleBufferLib = {}
  4. local component = require("component")
  5. local gpu = component.gpu
  6. --Символ пробела
  7. local charSpace = ' '
  8. local prevBuffer
  9.  
  10. doubleBufferLib.widthScreen, doubleBufferLib.heightScreen = gpu.getResolution()
  11.  
  12. --Очищает экран
  13. doubleBufferLib.clearScreen = function()
  14.     gpu.setForeground(0xffffff)
  15.     gpu.setBackground(0x000000)
  16.     gpu.fill(1, 1, doubleBufferLib.widthScreen, doubleBufferLib.heightScreen, charSpace)
  17. end
  18.  
  19. --Копирует таблицу
  20. doubleBufferLib.getCopyTable = function(table)
  21.     local copyTable = {}
  22.     for k, v in pairs(table) do
  23.         copyTable[k] = v
  24.     end
  25.     return copyTable
  26. end
  27.  
  28. --Вовзращает пустой буфер
  29. local function setEmptyBuffer()
  30.     local emptyBuffer = {}
  31.     for i = 1, doubleBufferLib.heightScreen do
  32.         for j = 1, doubleBufferLib.widthScreen do
  33.             table.insert(emptyBuffer, charSpace)
  34.             table.insert(emptyBuffer, 0xffffff)
  35.             table.insert(emptyBuffer, 0x000000)
  36.         end
  37.     end
  38.     return emptyBuffer
  39. end
  40.  
  41. --Меняет цвет переднего фона
  42. doubleBufferLib.setForeColor = function(color)
  43.     if gpu.getForeground() == color then
  44.         return false
  45.     else
  46.         gpu.setForeground(color)
  47.         return true
  48.     end
  49. end
  50.  
  51. --Меняет цвет заднего фона
  52. doubleBufferLib.setBackColor = function(color)
  53.     if gpu.getBackground() == color then
  54.         return false
  55.     else
  56.         gpu.setBackground(color)
  57.         return true
  58.     end
  59. end
  60.  
  61. --Возвращает индекс пикселя в буфере по координатам, кол-ву переменных, принадлежащих 1 пикселю, и ширине буфера
  62. doubleBufferLib.getIndexByCoords = function(x, y, numberItems, width)
  63.     width = width or doubleBufferLib.widthScreen
  64.     numberItems = numberItems or 1
  65.     return (y * width - width + x) * numberItems - numberItems
  66. end
  67.  
  68. --Функция сравнивает активный буфер экрана с заданным. Возвращает массив изменений
  69. local function compareBuffer(buffer)
  70.     local changedPix = {}
  71.     local char, foreColor, backColor
  72.     local curChar, curForeColor, curBackColor
  73.     local index
  74.     for i = 1, doubleBufferLib.heightScreen do
  75.         for j = 1, doubleBufferLib.widthScreen do
  76.             index = doubleBufferLib.getIndexByCoords(j, i, 3)
  77.             char, foreColor, backColor = buffer[index + 1], buffer[index + 2], buffer[index + 3]
  78.             curChar, curForeColor, curBackColor = prevBuffer[index + 1], prevBuffer[index + 2], prevBuffer[index + 3] -- gpu.get(j, i)
  79.             if not(char == curChar and foreColor == curForeColor and backColor == curBackColor) then
  80.                 table.insert(changedPix, j)
  81.                 table.insert(changedPix, i)
  82.                 table.insert(changedPix, char)
  83.                 table.insert(changedPix, foreColor)
  84.                 table.insert(changedPix, backColor)
  85.             end
  86.         end
  87.     end
  88.     return changedPix
  89. end
  90.  
  91. --Функция групирует пиксели по цвету
  92. local function groupByColor(changedPix)
  93.     if changedPix == nil then
  94.         return
  95.     end
  96.  
  97.     local colorArr = {} --Массив цветов и принадлежащих им пикселей
  98.  
  99.     local x, y, char
  100.     local foreColor, backColor
  101.     for i = 0, #changedPix - 1, 5 do
  102.         x, y, char = changedPix[i + 1], changedPix[i + 2], changedPix[i + 3]
  103.         foreColor, backColor = changedPix[i + 4], changedPix[i + 5]
  104.  
  105.         --Проверяет наличие пары переднего и заднего цвета
  106.         if i == 0 then
  107.             table.insert(colorArr, foreColor)
  108.             table.insert(colorArr, backColor)
  109.             table.insert(colorArr, {x, y, char})
  110.         else
  111.             local isColorExist = false
  112.             for j = 0, #colorArr - 1, 3 do
  113.                 local curForeColor, curBackColor = colorArr[j + 1], colorArr[j + 2]
  114.                 if curForeColor == foreColor and curBackColor == backColor then
  115.                     table.insert(colorArr[j + 3], x)
  116.                     table.insert(colorArr[j + 3], y)
  117.                     table.insert(colorArr[j + 3], char)
  118.                     isColorExist = true
  119.                     break
  120.                 end
  121.             end
  122.  
  123.             if not(isColorExist) then
  124.                 table.insert(colorArr, foreColor)
  125.                 table.insert(colorArr, backColor)
  126.                 table.insert(colorArr, {x, y, char})
  127.             end
  128.         end
  129.     end
  130.  
  131.     return colorArr
  132. end
  133.  
  134. --Функция возвращает пустую строку указанной длины
  135. local function isOneChar(str)
  136.     if #str == 1 then
  137.         return true
  138.     end
  139.     local isOneChar = false
  140.     for i = 2, #str do
  141.         if str:sub(i,i) == str:sub(i-1,i-1) then
  142.             isOneChar = true
  143.             break
  144.         end
  145.     end
  146.     return isOneChar
  147. end
  148.  
  149. --Группирует массив по строкам
  150. local function groupByRow(colorArr)
  151.     if colorArr == nil then
  152.         return
  153.     end
  154.  
  155.     local rowArr = {}
  156.     local foreColor, backColor
  157.     local pixArr
  158.     for i = 0, #colorArr - 1, 3 do
  159.         local sequenceArr = {}
  160.         foreColor, backColor = colorArr[i + 1], colorArr[i + 2]
  161.         table.insert(rowArr, foreColor)
  162.         table.insert(rowArr, backColor)
  163.  
  164.         pixArr = colorArr[i + 3]
  165.  
  166.         local prevX, prevY
  167.         local sequence
  168.         for j = 0, #pixArr - 1, 3 do
  169.             local curX, curY, curChar = pixArr[j + 1], pixArr[j + 2], pixArr[j + 3]
  170.             if curX - 1 == prevX and curY == prevY then
  171.                 sequence[3] = curX
  172.                 sequence[5] = sequence[5] .. curChar
  173.                
  174.             else
  175.                 if sequence ~= nil then
  176.                     table.insert(sequenceArr, sequence)
  177.                 end
  178.                 sequence = {}
  179.                 sequence[1], sequence[3] = curX, curX
  180.                 sequence[2], sequence[4] = curY, curY
  181.                 sequence[5] = curChar
  182.             end
  183.             --Последний или единтсвенный элемент в массиве
  184.             if j + 3 == #pixArr then
  185.                 table.insert(sequenceArr, sequence)
  186.             end
  187.  
  188.             prevX, prevY = curX, curY
  189.         end
  190.  
  191.         --Групировка по Y
  192.         if sequenceArr ~= nil then
  193.             local delSequinceIndexArr = {}
  194.             local prevSequence
  195.             local countSequence = 0
  196.             for j = 1, #sequenceArr do
  197.                 local curSequence = sequenceArr[j]
  198.                 local sequenceHeight = {}
  199.                 if prevSequence ~= nil then
  200.                     if prevSequence[4] == curSequence[4] - 1 and prevSequence[5] == curSequence[5] then
  201.                         countSequence = countSequence + 1
  202.                         prevSequence[4] = curSequence[4]
  203.                         prevSequence[2] = curSequence[4] - countSequence
  204.                         sequenceArr[j] = prevSequence
  205.  
  206.                         table.insert(delSequinceIndexArr, j - 1)
  207.  
  208.                         prevSequence = curSequence
  209.                     else
  210.                         countSequence = 0
  211.                         prevSequence = curSequence
  212.                     end
  213.                 else
  214.                     if isOneChar(curSequence[5]) then
  215.                         prevSequence = curSequence
  216.                         countSequence = 0
  217.                     end
  218.                 end
  219.             end
  220.  
  221.             if delSequinceIndexArr ~= nil then
  222.                 for j = #delSequinceIndexArr, 1, - 1 do
  223.                     table.remove(sequenceArr, delSequinceIndexArr[j])
  224.                 end
  225.             end  
  226.         end
  227.         table.insert(rowArr, sequenceArr)
  228.     end
  229.  
  230.     return rowArr
  231. end
  232.  
  233. local function group(changedPix)
  234.     local colorArr = groupByColor(changedPix)
  235.     local rowArr = groupByRow(colorArr)
  236.  
  237.     return rowArr
  238. end
  239.  
  240. --Отрисовывает указанный буфер
  241. doubleBufferLib.draw = function(buffer)
  242.     local changedPix = compareBuffer(buffer)
  243.     local rowArr = group(changedPix)
  244.     local colorOperation, drawOperation = 0, 0
  245.     if rowArr == nil then
  246.         return
  247.     end
  248.  
  249.     for i = 0, #rowArr - 1, 3 do
  250.         if doubleBufferLib.setForeColor(rowArr[i + 1]) then
  251.             colorOperation = colorOperation + 1
  252.         end
  253.         if doubleBufferLib.setBackColor(rowArr[i + 2]) then
  254.             colorOperation = colorOperation + 1
  255.         end
  256.  
  257.         local sequenceArr = rowArr[i + 3]
  258.  
  259.         for j = 1, #sequenceArr do
  260.             local sequence = sequenceArr[j]
  261.  
  262.             local x1, y1, x2, y2, str = sequence[1], sequence[2], sequence[3], sequence[4], sequence[5]
  263.             --print(x1, y1, x2, y2)
  264.             if y1 ~= y2 then
  265.                 local char = sequence[5]:sub(1, 1)
  266.                 local width, height = x2 - x1 + 1, y2 - y1 + 1
  267.                 gpu.fill(x1, y1, width, height, char)
  268.             else
  269.                 gpu.set(x1, y1, str)
  270.             end
  271.             drawOperation = drawOperation + 1
  272.         end
  273.     end
  274.  
  275.     --print("DRAWNING -", drawOperation, "COLOR -", colorOperation)
  276.  
  277.     prevBuffer = doubleBufferLib.getCopyTable(buffer)
  278. end
  279.  
  280. doubleBufferLib.getEmptyBuffer = function()
  281.     return doubleBufferLib.getCopyTable(doubleBufferLib.emptyBuffer)
  282. end
  283.  
  284. --Инициализация
  285. local function init()
  286.     doubleBufferLib.emptyBuffer = setEmptyBuffer()
  287.     prevBuffer = doubleBufferLib.getCopyTable(doubleBufferLib.emptyBuffer)
  288. end
  289.  
  290. init()
  291.  
  292. --Возвращает библиотеку
  293. return doubleBufferLib
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement