Petsox

doubleBuffering.lua

Aug 22nd, 2022
192
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.05 KB | Source Code | 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, evenYIndexStep, oddYIndexStep, realY, evenY =
  408. bufferWidth * (mathCeil(y / 2) - 1) + x,
  409. (bufferWidth - width),
  410. width
  411.  
  412. for pseudoY = y, y + height - 1 do
  413. realY = mathCeil(pseudoY / 2)
  414.  
  415. if realY >= drawLimitY1 and realY <= drawLimitY2 then
  416. evenY = pseudoY % 2 == 0
  417.  
  418. for pseudoX = x, x + width - 1 do
  419. if pseudoX >= drawLimitX1 and pseudoX <= drawLimitX2 then
  420. semiPixelRawSet(index, color, evenY)
  421. end
  422.  
  423. index = index + 1
  424. end
  425. else
  426. index = index + width
  427. end
  428.  
  429. if evenY then
  430. index = index + evenYIndexStep
  431. else
  432. index = index - oddYIndexStep
  433. end
  434. end
  435. end
  436.  
  437. local function drawSemiPixelLine(x1, y1, x2, y2, color)
  438. rasterizeLine(x1, y1, x2, y2, function(x, y)
  439. semiPixelSet(x, y, color)
  440. end)
  441. end
  442.  
  443. local function drawSemiPixelEllipse(centerX, centerY, radiusX, radiusY, color)
  444. rasterizeEllipse(centerX, centerY, radiusX, radiusY, function(x, y)
  445. semiPixelSet(x, y, color)
  446. end)
  447. end
  448.  
  449. --------------------------------------------------------------------------------
  450.  
  451. local function getPointTimedPosition(firstPoint, secondPoint, time)
  452. return {
  453. x = firstPoint.x + (secondPoint.x - firstPoint.x) * time,
  454. y = firstPoint.y + (secondPoint.y - firstPoint.y) * time
  455. }
  456. end
  457.  
  458. local function getConnectionPoints(points, time)
  459. local connectionPoints = {}
  460. for point = 1, #points - 1 do
  461. tableInsert(connectionPoints, getPointTimedPosition(points[point], points[point + 1], time))
  462. end
  463. return connectionPoints
  464. end
  465.  
  466. local function getMainPointPosition(points, time)
  467. if #points > 1 then
  468. return getMainPointPosition(getConnectionPoints(points, time), time)
  469. else
  470. return points[1]
  471. end
  472. end
  473.  
  474. local function drawSemiPixelCurve(points, color, precision)
  475. local linePoints = {}
  476. for time = 0, 1, precision or 0.01 do
  477. tableInsert(linePoints, getMainPointPosition(points, time))
  478. end
  479.  
  480. for point = 1, #linePoints - 1 do
  481. drawSemiPixelLine(mathFloor(linePoints[point].x), mathFloor(linePoints[point].y), mathFloor(linePoints[point + 1].x), mathFloor(linePoints[point + 1].y), color)
  482. end
  483. end
  484.  
  485. --------------------------------------------------------------------------------
  486.  
  487. local function drawChanges(force)
  488. local index, indexStepOnEveryLine, changes = bufferWidth * (drawLimitY1 - 1) + drawLimitX1, (bufferWidth - drawLimitX2 + drawLimitX1 - 1), {}
  489. local x, equalChars, equalCharsIndex, charX, charIndex, currentForeground
  490. local currentFrameBackground, currentFrameForeground, currentFrameSymbol, changesCurrentFrameBackground, changesCurrentFrameBackgroundCurrentFrameForeground
  491.  
  492. local changesCurrentFrameBackgroundCurrentFrameForegroundIndex
  493.  
  494. for y = drawLimitY1, drawLimitY2 do
  495. x = drawLimitX1
  496. while x <= drawLimitX2 do
  497. -- Determine if some pixel data was changed (or if <force> argument was passed)
  498. if
  499. currentFrameBackgrounds[index] ~= newFrameBackgrounds[index] or
  500. currentFrameForegrounds[index] ~= newFrameForegrounds[index] or
  501. currentFrameSymbols[index] ~= newFrameSymbols[index] or
  502. force
  503. then
  504. -- Make pixel at both frames equal
  505. currentFrameBackground, currentFrameForeground, currentFrameSymbol = newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  506. currentFrameBackgrounds[index] = currentFrameBackground
  507. currentFrameForegrounds[index] = currentFrameForeground
  508. currentFrameSymbols[index] = currentFrameSymbol
  509.  
  510. -- Look for pixels with equal chars from right of current pixel
  511. equalChars, equalCharsIndex, charX, charIndex = {currentFrameSymbol}, 2, x + 1, index + 1
  512. while charX <= drawLimitX2 do
  513. -- Pixels becomes equal only if they have same background and (whitespace char or same foreground)
  514. if
  515. currentFrameBackground == newFrameBackgrounds[charIndex] and
  516. (
  517. newFrameSymbols[charIndex] == " " or
  518. currentFrameForeground == newFrameForegrounds[charIndex]
  519. )
  520. then
  521. -- Make pixel at both frames equal
  522. currentFrameBackgrounds[charIndex] = newFrameBackgrounds[charIndex]
  523. currentFrameForegrounds[charIndex] = newFrameForegrounds[charIndex]
  524. currentFrameSymbols[charIndex] = newFrameSymbols[charIndex]
  525.  
  526. equalChars[equalCharsIndex], equalCharsIndex = currentFrameSymbols[charIndex], equalCharsIndex + 1
  527. else
  528. break
  529. end
  530.  
  531. charX, charIndex = charX + 1, charIndex + 1
  532. end
  533.  
  534. -- Group pixels that need to be drawn by background and foreground
  535. changes[currentFrameBackground] = changes[currentFrameBackground] or {}
  536. changesCurrentFrameBackground = changes[currentFrameBackground]
  537. changesCurrentFrameBackground[currentFrameForeground] = changesCurrentFrameBackground[currentFrameForeground] or {index = 1}
  538. changesCurrentFrameBackgroundCurrentFrameForeground = changesCurrentFrameBackground[currentFrameForeground]
  539. changesCurrentFrameBackgroundCurrentFrameForegroundIndex = changesCurrentFrameBackgroundCurrentFrameForeground.index
  540.  
  541. changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = x, changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  542. changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = y, changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  543. changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = tableConcat(equalChars), changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  544.  
  545. x, index, changesCurrentFrameBackgroundCurrentFrameForeground.index = x + equalCharsIndex - 2, index + equalCharsIndex - 2, changesCurrentFrameBackgroundCurrentFrameForegroundIndex
  546. end
  547.  
  548. x, index = x + 1, index + 1
  549. end
  550.  
  551. index = index + indexStepOnEveryLine
  552. end
  553.  
  554. -- Draw grouped pixels on screen
  555. for background, foregrounds in pairs(changes) do
  556. GPUProxySetBackground(background)
  557.  
  558. for foreground, pixels in pairs(foregrounds) do
  559. if currentForeground ~= foreground then
  560. GPUProxySetForeground(foreground)
  561. currentForeground = foreground
  562. end
  563.  
  564. for i = 1, #pixels, 3 do
  565. GPUProxySet(pixels[i], pixels[i + 1], pixels[i + 2])
  566. end
  567. end
  568. end
  569.  
  570. changes = nil
  571. end
  572.  
  573. --------------------------------------------------------------------------------
  574.  
  575. bindGPU(component.getPrimary("gpu").address)
  576.  
  577. return {
  578. getCoordinates = getCoordinates,
  579. getIndex = getIndex,
  580. setDrawLimit = setDrawLimit,
  581. resetDrawLimit = resetDrawLimit,
  582. getDrawLimit = getDrawLimit,
  583. flush = flush,
  584. setResolution = setResolution,
  585. bindScreen = bindScreen,
  586. bindGPU = bindGPU,
  587. getGPUProxy = getGPUProxy,
  588. getResolution = getResolution,
  589. getWidth = getWidth,
  590. getHeight = getHeight,
  591. getCurrentFrameTables = getCurrentFrameTables,
  592. getNewFrameTables = getNewFrameTables,
  593.  
  594. rawSet = rawSet,
  595. rawGet = rawGet,
  596. get = get,
  597. set = set,
  598. clear = clear,
  599. copy = copy,
  600. paste = paste,
  601. rasterizeLine = rasterizeLine,
  602. rasterizeEllipse = rasterizeEllipse,
  603. semiPixelRawSet = semiPixelRawSet,
  604. semiPixelSet = semiPixelSet,
  605. drawChanges = drawChanges,
  606.  
  607. drawRectangle = drawRectangle,
  608. drawLine = drawLine,
  609. drawEllipse = drawEllipse,
  610. drawText = drawText,
  611. drawImage = drawImage,
  612. drawFrame = drawFrame,
  613.  
  614. drawSemiPixelRectangle = drawSemiPixelRectangle,
  615. drawSemiPixelLine = drawSemiPixelLine,
  616. drawSemiPixelEllipse = drawSemiPixelEllipse,
  617. drawSemiPixelCurve = drawSemiPixelCurve,
  618. }
Add Comment
Please, Sign In to add comment