oGoOgO

DoubleBuffering.lua

Jun 3rd, 2024
34
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.67 KB | None | 0 0
  1.  
  2. local component = require("component")
  3. local unicode = require("unicode")
  4. local color = require("color")
  5. local image = require("image")
  6.  
  7. --------------------------------------------------------------------------------
  8.  
  9. local bufferWidth, bufferHeight
  10. local currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols, newFrameBackgrounds, newFrameForegrounds, newFrameSymbols
  11. local drawLimitX1, drawLimitX2, drawLimitY1, drawLimitY2
  12. local GPUProxy, GPUProxyGetResolution, GPUProxySetResolution, GPUProxyBind, GPUProxyGetBackground, GPUProxyGetForeground, GPUProxySetBackground, GPUProxySetForeground, GPUProxyGet, GPUProxySet, GPUProxyFill
  13.  
  14. local mathCeil, mathFloor, mathModf, mathAbs = math.ceil, math.floor, math.modf, math.abs
  15. local tableInsert, tableConcat = table.insert, table.concat
  16. local colorBlend = color.blend
  17. local unicodeLen, unicodeSub = unicode.len, unicode.sub
  18.  
  19. --------------------------------------------------------------------------------
  20.  
  21. local function getIndex(x, y)
  22. return bufferWidth * (y - 1) + x
  23. end
  24.  
  25. local function getCurrentFrameTables()
  26. return currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols
  27. end
  28.  
  29. local function getNewFrameTables()
  30. return newFrameBackgrounds, newFrameForegrounds, newFrameSymbols
  31. end
  32.  
  33. --------------------------------------------------------------------------------
  34.  
  35. local function setDrawLimit(x1, y1, x2, y2)
  36. drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = x1, y1, x2, y2
  37. end
  38.  
  39. local function resetDrawLimit()
  40. drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = 1, 1, bufferWidth, bufferHeight
  41. end
  42.  
  43. local function getDrawLimit()
  44. return drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2
  45. end
  46.  
  47. --------------------------------------------------------------------------------
  48.  
  49. local function flush(width, height)
  50. if not width or not height then
  51. width, height = GPUProxyGetResolution()
  52. end
  53.  
  54. currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols, newFrameBackgrounds, newFrameForegrounds, newFrameSymbols = {}, {}, {}, {}, {}, {}
  55. bufferWidth = width
  56. bufferHeight = height
  57. resetDrawLimit()
  58.  
  59. for y = 1, bufferHeight do
  60. for x = 1, bufferWidth do
  61. tableInsert(currentFrameBackgrounds, 0x010101)
  62. tableInsert(currentFrameForegrounds, 0xFEFEFE)
  63. tableInsert(currentFrameSymbols, " ")
  64.  
  65. tableInsert(newFrameBackgrounds, 0x010101)
  66. tableInsert(newFrameForegrounds, 0xFEFEFE)
  67. tableInsert(newFrameSymbols, " ")
  68. end
  69. end
  70. end
  71.  
  72. local function setResolution(width, height)
  73. GPUProxySetResolution(width, height)
  74. flush(width, height)
  75. end
  76.  
  77. local function getResolution()
  78. return bufferWidth, bufferHeight
  79. end
  80.  
  81. local function getWidth()
  82. return bufferWidth
  83. end
  84.  
  85. local function getHeight()
  86. return bufferHeight
  87. end
  88.  
  89. local function bindScreen(...)
  90. GPUProxyBind(...)
  91. flush(GPUProxyGetResolution())
  92. end
  93.  
  94. local function getGPUProxy()
  95. return GPUProxy
  96. end
  97.  
  98. local function updateGPUProxyMethods()
  99. GPUProxyGet = GPUProxy.get
  100. GPUProxyGetResolution = GPUProxy.getResolution
  101. GPUProxyGetBackground = GPUProxy.getBackground
  102. GPUProxyGetForeground = GPUProxy.getForeground
  103.  
  104. GPUProxySet = GPUProxy.set
  105. GPUProxySetResolution = GPUProxy.setResolution
  106. GPUProxySetBackground = GPUProxy.setBackground
  107. GPUProxySetForeground = GPUProxy.setForeground
  108.  
  109. GPUProxyBind = GPUProxy.bind
  110. GPUProxyFill = GPUProxy.fill
  111. end
  112.  
  113. local function bindGPU(address)
  114. GPUProxy = component.proxy(address)
  115. updateGPUProxyMethods()
  116. flush(GPUProxyGetResolution())
  117. end
  118.  
  119. --------------------------------------------------------------------------------
  120.  
  121. local function rawSet(index, background, foreground, symbol)
  122. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
  123. end
  124.  
  125. local function rawGet(index)
  126. return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  127. end
  128.  
  129. local function get(x, y)
  130. if x >= 1 and y >= 1 and x <= bufferWidth and y <= bufferHeight then
  131. local index = bufferWidth * (y - 1) + x
  132. return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  133. else
  134. return 0x000000, 0x000000, " "
  135. end
  136. end
  137.  
  138. local function set(x, y, background, foreground, symbol)
  139. if x >= drawLimitX1 and y >= drawLimitY1 and x <= drawLimitX2 and y <= drawLimitY2 then
  140. local index = bufferWidth * (y - 1) + x
  141. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
  142. end
  143. end
  144.  
  145. local function drawRectangle(x, y, width, height, background, foreground, symbol, transparency)
  146. local index, indexStepOnReachOfSquareWidth = bufferWidth * (y - 1) + x, bufferWidth - width
  147. for j = y, y + height - 1 do
  148. if j >= drawLimitY1 and j <= drawLimitY2 then
  149. for i = x, x + width - 1 do
  150. if i >= drawLimitX1 and i <= drawLimitX2 then
  151. if transparency then
  152. newFrameBackgrounds[index], newFrameForegrounds[index] =
  153. colorBlend(newFrameBackgrounds[index], background, transparency),
  154. colorBlend(newFrameForegrounds[index], background, transparency)
  155. else
  156. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
  157. end
  158. end
  159.  
  160. index = index + 1
  161. end
  162.  
  163. index = index + indexStepOnReachOfSquareWidth
  164. else
  165. index = index + bufferWidth
  166. end
  167. end
  168. end
  169.  
  170. local function clear(color, transparency)
  171. drawRectangle(1, 1, bufferWidth, bufferHeight, color or 0x0, 0x000000, " ", transparency)
  172. end
  173.  
  174. local function copy(x, y, width, height)
  175. local copyArray, index = { width, height }
  176.  
  177. for j = y, y + height - 1 do
  178. for i = x, x + width - 1 do
  179. if i >= 1 and j >= 1 and i <= bufferWidth and j <= bufferHeight then
  180. index = bufferWidth * (j - 1) + i
  181. tableInsert(copyArray, newFrameBackgrounds[index])
  182. tableInsert(copyArray, newFrameForegrounds[index])
  183. tableInsert(copyArray, newFrameSymbols[index])
  184. else
  185. tableInsert(copyArray, 0x0)
  186. tableInsert(copyArray, 0x0)
  187. tableInsert(copyArray, " ")
  188. end
  189. end
  190. end
  191.  
  192. return copyArray
  193. end
  194.  
  195. local function paste(startX, startY, picture)
  196. local imageWidth = picture[1]
  197. local bufferIndex, pictureIndex, bufferIndexStepOnReachOfImageWidth = bufferWidth * (startY - 1) + startX, 3, bufferWidth - imageWidth
  198.  
  199. for y = startY, startY + picture[2] - 1 do
  200. if y >= drawLimitY1 and y <= drawLimitY2 then
  201. for x = startX, startX + imageWidth - 1 do
  202. if x >= drawLimitX1 and x <= drawLimitX2 then
  203. newFrameBackgrounds[bufferIndex] = picture[pictureIndex]
  204. newFrameForegrounds[bufferIndex] = picture[pictureIndex + 1]
  205. newFrameSymbols[bufferIndex] = picture[pictureIndex + 2]
  206. end
  207.  
  208. bufferIndex, pictureIndex = bufferIndex + 1, pictureIndex + 3
  209. end
  210.  
  211. bufferIndex = bufferIndex + bufferIndexStepOnReachOfImageWidth
  212. else
  213. bufferIndex, pictureIndex = bufferIndex + bufferWidth, pictureIndex + imageWidth * 3
  214. end
  215. end
  216. end
  217.  
  218. local function rasterizeLine(x1, y1, x2, y2, method)
  219. local inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = x1, x2, y1, y2, false, mathAbs(x2 - x1), mathAbs(y2 - y1)
  220. if inLoopValueDelta < outLoopValueDelta then
  221. inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = y1, y2, x1, x2, true, outLoopValueDelta, inLoopValueDelta
  222. end
  223.  
  224. if outLoopValueFrom > outLoopValueTo then
  225. outLoopValueFrom, outLoopValueTo = outLoopValueTo, outLoopValueFrom
  226. inLoopValueFrom, inLoopValueTo = inLoopValueTo, inLoopValueFrom
  227. end
  228.  
  229. local outLoopValue, outLoopValueCounter, outLoopValueTriggerIncrement = outLoopValueFrom, 1, inLoopValueDelta / outLoopValueDelta
  230. local outLoopValueTrigger = outLoopValueTriggerIncrement
  231. for inLoopValue = inLoopValueFrom, inLoopValueTo, inLoopValueFrom < inLoopValueTo and 1 or -1 do
  232. if isReversed then
  233. method(outLoopValue, inLoopValue)
  234. else
  235. method(inLoopValue, outLoopValue)
  236. end
  237.  
  238. outLoopValueCounter = outLoopValueCounter + 1
  239. if outLoopValueCounter > outLoopValueTrigger then
  240. outLoopValue, outLoopValueTrigger = outLoopValue + 1, outLoopValueTrigger + outLoopValueTriggerIncrement
  241. end
  242. end
  243. end
  244.  
  245. local function rasterizeEllipse(centerX, centerY, radiusX, radiusY, method)
  246. local function rasterizeEllipsePoints(XP, YP)
  247. method(centerX + XP, centerY + YP)
  248. method(centerX - XP, centerY + YP)
  249. method(centerX - XP, centerY - YP)
  250. method(centerX + XP, centerY - YP)
  251. end
  252.  
  253. local x, y, changeX, changeY, ellipseError, twoASquare, twoBSquare = radiusX, 0, radiusY * radiusY * (1 - 2 * radiusX), radiusX * radiusX, 0, 2 * radiusX * radiusX, 2 * radiusY * radiusY
  254. local stoppingX, stoppingY = twoBSquare * radiusX, 0
  255.  
  256. while stoppingX >= stoppingY do
  257. rasterizeEllipsePoints(x, y)
  258.  
  259. y, stoppingY, ellipseError = y + 1, stoppingY + twoASquare, ellipseError + changeY
  260. changeY = changeY + twoASquare
  261.  
  262. if (2 * ellipseError + changeX) > 0 then
  263. x, stoppingX, ellipseError = x - 1, stoppingX - twoBSquare, ellipseError + changeX
  264. changeX = changeX + twoBSquare
  265. end
  266. end
  267.  
  268. x, y, changeX, changeY, ellipseError, stoppingX, stoppingY = 0, radiusY, radiusY * radiusY, radiusX * radiusX * (1 - 2 * radiusY), 0, 0, twoASquare * radiusY
  269.  
  270. while stoppingX <= stoppingY do
  271. rasterizeEllipsePoints(x, y)
  272.  
  273. x, stoppingX, ellipseError = x + 1, stoppingX + twoBSquare, ellipseError + changeX
  274. changeX = changeX + twoBSquare
  275.  
  276. if (2 * ellipseError + changeY) > 0 then
  277. y, stoppingY, ellipseError = y - 1, stoppingY - twoASquare, ellipseError + changeY
  278. changeY = changeY + twoASquare
  279. end
  280. end
  281. end
  282.  
  283. local function drawLine(x1, y1, x2, y2, background, foreground, symbol)
  284. rasterizeLine(x1, y1, x2, y2, function(x, y)
  285. set(x, y, background, foreground, symbol)
  286. end)
  287. end
  288.  
  289. local function drawEllipse(centerX, centerY, radiusX, radiusY, background, foreground, symbol)
  290. rasterizeEllipse(centerX, centerY, radiusX, radiusY, function(x, y)
  291. set(x, y, background, foreground, symbol)
  292. end)
  293. end
  294.  
  295. local function drawText(x, y, textColor, data, transparency)
  296. if y >= drawLimitY1 and y <= drawLimitY2 then
  297. local charIndex, bufferIndex = 1, bufferWidth * (y - 1) + x
  298.  
  299. for charIndex = 1, unicodeLen(data) do
  300. if x >= drawLimitX1 and x <= drawLimitX2 then
  301. if transparency then
  302. newFrameForegrounds[bufferIndex] = colorBlend(newFrameBackgrounds[bufferIndex], textColor, transparency)
  303. else
  304. newFrameForegrounds[bufferIndex] = textColor
  305. end
  306.  
  307. newFrameSymbols[bufferIndex] = unicodeSub(data, charIndex, charIndex)
  308. end
  309.  
  310. x, bufferIndex = x + 1, bufferIndex + 1
  311. end
  312. end
  313. end
  314.  
  315. local function drawImage(startX, startY, picture, blendForeground)
  316. local bufferIndex, pictureIndex, imageWidth, backgrounds, foregrounds, alphas, symbols = bufferWidth * (startY - 1) + startX, 1, picture[1], picture[3], picture[4], picture[5], picture[6]
  317. local bufferIndexStepOnReachOfImageWidth = bufferWidth - imageWidth
  318.  
  319. for y = startY, startY + picture[2] - 1 do
  320. if y >= drawLimitY1 and y <= drawLimitY2 then
  321. for x = startX, startX + imageWidth - 1 do
  322. if x >= drawLimitX1 and x <= drawLimitX2 then
  323. if alphas[pictureIndex] == 0 then
  324. newFrameBackgrounds[bufferIndex], newFrameForegrounds[bufferIndex] = backgrounds[pictureIndex], foregrounds[pictureIndex]
  325. elseif alphas[pictureIndex] > 0 and alphas[pictureIndex] < 1 then
  326. newFrameBackgrounds[bufferIndex] = colorBlend(newFrameBackgrounds[bufferIndex], backgrounds[pictureIndex], alphas[pictureIndex])
  327.  
  328. if blendForeground then
  329. newFrameForegrounds[bufferIndex] = colorBlend(newFrameForegrounds[bufferIndex], foregrounds[pictureIndex], alphas[pictureIndex])
  330. else
  331. newFrameForegrounds[bufferIndex] = foregrounds[pictureIndex]
  332. end
  333. elseif alphas[pictureIndex] == 1 and symbols[pictureIndex] ~= " " then
  334. newFrameForegrounds[bufferIndex] = foregrounds[pictureIndex]
  335. end
  336.  
  337. newFrameSymbols[bufferIndex] = symbols[pictureIndex]
  338. end
  339.  
  340. bufferIndex, pictureIndex = bufferIndex + 1, pictureIndex + 1
  341. end
  342.  
  343. bufferIndex = bufferIndex + bufferIndexStepOnReachOfImageWidth
  344. else
  345. bufferIndex, pictureIndex = bufferIndex + bufferWidth, pictureIndex + imageWidth
  346. end
  347. end
  348. end
  349.  
  350. local function drawFrame(x, y, width, height, color)
  351. local stringUp, stringDown, x2 = "┌" .. string.rep("─", width - 2) .. "┐", "└" .. string.rep("─", width - 2) .. "┘", x + width - 1
  352.  
  353. drawText(x, y, color, stringUp); y = y + 1
  354. for i = 1, height - 2 do
  355. drawText(x, y, color, "│")
  356. drawText(x2, y, color, "│")
  357. y = y + 1
  358. end
  359. drawText(x, y, color, stringDown)
  360. end
  361.  
  362. --------------------------------------------------------------------------------
  363.  
  364. local function semiPixelRawSet(index, color, yPercentTwoEqualsZero)
  365. local upperPixel, lowerPixel, bothPixel = "▀", "▄", " "
  366. local background, foreground, symbol = newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  367.  
  368. if yPercentTwoEqualsZero then
  369. if symbol == upperPixel then
  370. if color == foreground then
  371. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, bothPixel
  372. else
  373. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, symbol
  374. end
  375. elseif symbol == bothPixel then
  376. if color ~= background then
  377. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, lowerPixel
  378. end
  379. else
  380. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, lowerPixel
  381. end
  382. else
  383. if symbol == lowerPixel then
  384. if color == foreground then
  385. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, bothPixel
  386. else
  387. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, symbol
  388. end
  389. elseif symbol == bothPixel then
  390. if color ~= background then
  391. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, upperPixel
  392. end
  393. else
  394. newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, upperPixel
  395. end
  396. end
  397. end
  398.  
  399. local function semiPixelSet(x, y, color)
  400. local yFixed = mathCeil(y / 2)
  401. if x >= drawLimitX1 and yFixed >= drawLimitY1 and x <= drawLimitX2 and yFixed <= drawLimitY2 then
  402. semiPixelRawSet(bufferWidth * (yFixed - 1) + x, color, y % 2 == 0)
  403. end
  404. end
  405.  
  406. local function drawSemiPixelRectangle(x, y, width, height, color)
  407. local index, indexStepForward, indexStepBackward, jPercentTwoEqualsZero, jFixed = bufferWidth * (mathCeil(y / 2) - 1) + x, (bufferWidth - width), width
  408. for j = y, y + height - 1 do
  409. jPercentTwoEqualsZero = j % 2 == 0
  410.  
  411. for i = x, x + width - 1 do
  412. jFixed = mathCeil(j / 2)
  413. semiPixelRawSet(index, color, jPercentTwoEqualsZero)
  414. index = index + 1
  415. end
  416.  
  417. if jPercentTwoEqualsZero then
  418. index = index + indexStepForward
  419. else
  420. index = index - indexStepBackward
  421. end
  422. end
  423. end
  424.  
  425. local function drawSemiPixelLine(x1, y1, x2, y2, color)
  426. rasterizeLine(x1, y1, x2, y2, function(x, y)
  427. semiPixelSet(x, y, color)
  428. end)
  429. end
  430.  
  431. local function drawSemiPixelEllipse(centerX, centerY, radiusX, radiusY, color)
  432. rasterizeEllipse(centerX, centerY, radiusX, radiusY, function(x, y)
  433. semiPixelSet(x, y, color)
  434. end)
  435. end
  436.  
  437. --------------------------------------------------------------------------------
  438.  
  439. local function getPointTimedPosition(firstPoint, secondPoint, time)
  440. return {
  441. x = firstPoint.x + (secondPoint.x - firstPoint.x) * time,
  442. y = firstPoint.y + (secondPoint.y - firstPoint.y) * time
  443. }
  444. end
  445.  
  446. local function getConnectionPoints(points, time)
  447. local connectionPoints = {}
  448. for point = 1, #points - 1 do
  449. tableInsert(connectionPoints, getPointTimedPosition(points[point], points[point + 1], time))
  450. end
  451. return connectionPoints
  452. end
  453.  
  454. local function getMainPointPosition(points, time)
  455. if #points > 1 then
  456. return getMainPointPosition(getConnectionPoints(points, time), time)
  457. else
  458. return points[1]
  459. end
  460. end
  461.  
  462. local function drawSemiPixelCurve(points, color, precision)
  463. local linePoints = {}
  464. for time = 0, 1, precision or 0.01 do
  465. tableInsert(linePoints, getMainPointPosition(points, time))
  466. end
  467.  
  468. for point = 1, #linePoints - 1 do
  469. drawSemiPixelLine(mathFloor(linePoints[point].x), mathFloor(linePoints[point].y), mathFloor(linePoints[point + 1].x), mathFloor(linePoints[point + 1].y), color)
  470. end
  471. end
  472.  
  473. --------------------------------------------------------------------------------
  474.  
  475. local function drawChanges(force)
  476. local index, indexStepOnEveryLine, changes = bufferWidth * (drawLimitY1 - 1) + drawLimitX1, (bufferWidth - drawLimitX2 + drawLimitX1 - 1), {}
  477. local x, equalChars, equalCharsIndex, charX, charIndex, currentForeground
  478. local currentFrameBackground, currentFrameForeground, currentFrameSymbol, changesCurrentFrameBackground, changesCurrentFrameBackgroundCurrentFrameForeground
  479.  
  480. local changesCurrentFrameBackgroundCurrentFrameForegroundIndex
  481.  
  482. for y = drawLimitY1, drawLimitY2 do
  483. x = drawLimitX1
  484. while x <= drawLimitX2 do
  485. -- Determine if some pixel data was changed (or if <force> argument was passed)
  486. if
  487. currentFrameBackgrounds[index] ~= newFrameBackgrounds[index] or
  488. currentFrameForegrounds[index] ~= newFrameForegrounds[index] or
  489. currentFrameSymbols[index] ~= newFrameSymbols[index] or
  490. force
  491. then
  492. -- Make pixel at both frames equal
  493. currentFrameBackground, currentFrameForeground, currentFrameSymbol = newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  494. currentFrameBackgrounds[index] = currentFrameBackground
  495. currentFrameForegrounds[index] = currentFrameForeground
  496. currentFrameSymbols[index] = currentFrameSymbol
  497.  
  498. -- Look for pixels with equal chars from right of current pixel
  499. equalChars, equalCharsIndex, charX, charIndex = {currentFrameSymbol}, 2, x + 1, index + 1
  500. while charX <= drawLimitX2 do
  501. -- Pixels becomes equal only if they have same background and (whitespace char or same foreground)
  502. if
  503. currentFrameBackground == newFrameBackgrounds[charIndex] and
  504. (
  505. newFrameSymbols[charIndex] == " " or
  506. currentFrameForeground == newFrameForegrounds[charIndex]
  507. )
  508. then
  509. -- Make pixel at both frames equal
  510. currentFrameBackgrounds[charIndex] = newFrameBackgrounds[charIndex]
  511. currentFrameForegrounds[charIndex] = newFrameForegrounds[charIndex]
  512. currentFrameSymbols[charIndex] = newFrameSymbols[charIndex]
  513.  
  514. equalChars[equalCharsIndex], equalCharsIndex = currentFrameSymbols[charIndex], equalCharsIndex + 1
  515. else
  516. break
  517. end
  518.  
  519. charX, charIndex = charX + 1, charIndex + 1
  520. end
  521.  
  522. -- Group pixels that need to be drawn by background and foreground
  523. changes[currentFrameBackground] = changes[currentFrameBackground] or {}
  524. changesCurrentFrameBackground = changes[currentFrameBackground]
  525. changesCurrentFrameBackground[currentFrameForeground] = changesCurrentFrameBackground[currentFrameForeground] or {index = 1}
  526. changesCurrentFrameBackgroundCurrentFrameForeground = changesCurrentFrameBackground[currentFrameForeground]
  527. changesCurrentFrameBackgroundCurrentFrameForegroundIndex = changesCurrentFrameBackgroundCurrentFrameForeground.index
  528.  
  529. changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = x, changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  530. changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = y, changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  531. changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = tableConcat(equalChars), changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  532.  
  533. x, index, changesCurrentFrameBackgroundCurrentFrameForeground.index = x + equalCharsIndex - 2, index + equalCharsIndex - 2, changesCurrentFrameBackgroundCurrentFrameForegroundIndex
  534. end
  535.  
  536. x, index = x + 1, index + 1
  537. end
  538.  
  539. index = index + indexStepOnEveryLine
  540. end
  541.  
  542. -- Draw grouped pixels on screen
  543. for background, foregrounds in pairs(changes) do
  544. GPUProxySetBackground(background)
  545.  
  546. for foreground, pixels in pairs(foregrounds) do
  547. if currentForeground ~= foreground then
  548. GPUProxySetForeground(foreground)
  549. currentForeground = foreground
  550. end
  551.  
  552. for i = 1, #pixels, 3 do
  553. GPUProxySet(pixels[i], pixels[i + 1], pixels[i + 2])
  554. end
  555. end
  556. end
  557.  
  558. changes = nil
  559. end
  560.  
  561. --------------------------------------------------------------------------------
  562.  
  563. bindGPU(component.getPrimary("gpu").address)
  564.  
  565. return {
  566. getCoordinates = getCoordinates,
  567. getIndex = getIndex,
  568. setDrawLimit = setDrawLimit,
  569. resetDrawLimit = resetDrawLimit,
  570. getDrawLimit = getDrawLimit,
  571. flush = flush,
  572. setResolution = setResolution,
  573. bindScreen = bindScreen,
  574. bindGPU = bindGPU,
  575. getGPUProxy = getGPUProxy,
  576. getResolution = getResolution,
  577. getWidth = getWidth,
  578. getHeight = getHeight,
  579. getCurrentFrameTables = getCurrentFrameTables,
  580. getNewFrameTables = getNewFrameTables,
  581.  
  582. rawSet = rawSet,
  583. rawGet = rawGet,
  584. get = get,
  585. set = set,
  586. clear = clear,
  587. copy = copy,
  588. paste = paste,
  589. rasterizeLine = rasterizeLine,
  590. rasterizeEllipse = rasterizeEllipse,
  591. semiPixelRawSet = semiPixelRawSet,
  592. semiPixelSet = semiPixelSet,
  593. drawChanges = drawChanges,
  594.  
  595. drawRectangle = drawRectangle,
  596. drawLine = drawLine,
  597. drawEllipse = drawEllipse,
  598. drawText = drawText,
  599. drawImage = drawImage,
  600. drawFrame = drawFrame,
  601.  
  602. drawSemiPixelRectangle = drawSemiPixelRectangle,
  603. drawSemiPixelLine = drawSemiPixelLine,
  604. drawSemiPixelEllipse = drawSemiPixelEllipse,
  605. drawSemiPixelCurve = drawSemiPixelCurve,
  606. }
Add Comment
Please, Sign In to add comment