Advertisement
VlaD00m

NyaDraw Graphic Engine

Feb 20th, 2021 (edited)
896
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 36.10 KB | None | 0 0
  1. --[[NyaDraw Graphic Engine v1.20 for OpenOS
  2.     Standalone "Screen.lua" port from MineOS
  3.     More info on: https://github.com/Bs0Dd/OpenCompSoft/blob/master/NyaDraw/README.md
  4.     2015-2023 - ECS: https://github.com/IgorTimofeev
  5.     2021-2023 - Bs0Dd: https://github.com/Bs0Dd
  6. ]]
  7.  
  8. local unicode = require("unicode")
  9. local computer = require("computer")
  10. local component = require("component")
  11. local bit32 = require("bit32")
  12.  
  13. --------------------------------------------------------------------------------
  14.  
  15. local
  16.     componentInvoke,
  17.  
  18.     mathCeil,
  19.     mathFloor,
  20.     mathAbs,
  21.     mathMin,
  22.     mathMax,
  23.  
  24.     tableInsert,
  25.     tableConcat,
  26.  
  27.     unicodeLen,
  28.     unicodeSub,
  29.  
  30.     bufferWidth,
  31.     bufferHeight,
  32.  
  33.     currentFrameBackgrounds,
  34.     currentFrameForegrounds,
  35.     currentFrameSymbols,
  36.     newFrameBackgrounds,
  37.     newFrameForegrounds,
  38.     newFrameSymbols,
  39.  
  40.     drawLimitX1,
  41.     drawLimitX2,
  42.     drawLimitY1,
  43.     drawLimitY2,
  44.  
  45.     GPUAddress =
  46.  
  47.     component.invoke,
  48.  
  49.     math.ceil,
  50.     math.floor,
  51.     math.abs,
  52.     math.min,
  53.     math.max,
  54.  
  55.     table.insert,
  56.     table.concat,
  57.  
  58.     unicode.len,
  59.     unicode.sub;
  60.  
  61. --------------------------------------------------------------------------------
  62.  
  63. local function getIndex(x, y)
  64.     return bufferWidth * (y - 1) + x
  65. end
  66.  
  67. local function getCurrentFrameTables()
  68.     return currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols
  69. end
  70.  
  71. local function getNewFrameTables()
  72.     return newFrameBackgrounds, newFrameForegrounds, newFrameSymbols
  73. end
  74.  
  75. --------------------------------------------------------------------------------
  76.  
  77. local function setDrawLimit(x1, y1, x2, y2)
  78.     drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = x1, y1, x2, y2
  79. end
  80.  
  81. local function resetDrawLimit()
  82.     drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = 1, 1, bufferWidth, bufferHeight
  83. end
  84.  
  85. local function getDrawLimit()
  86.     return drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2
  87. end
  88.  
  89. --------------------------------------------------------------------------------
  90. --Color Subsystem (Ported by Bs()Dd)
  91.  
  92. local palette = {0x000000, 0x000040, 0x000080, 0x0000BF, 0x0000FF, 0x002400, 0x002440, 0x002480, 0x0024BF, 0x0024FF, 0x004900, 0x004940,
  93. 0x004980, 0x0049BF, 0x0049FF, 0x006D00, 0x006D40, 0x006D80, 0x006DBF, 0x006DFF, 0x009200, 0x009240, 0x009280, 0x0092BF, 0x0092FF, 0x00B600,
  94. 0x00B640, 0x00B680, 0x00B6BF, 0x00B6FF, 0x00DB00, 0x00DB40, 0x00DB80, 0x00DBBF, 0x00DBFF, 0x00FF00, 0x00FF40, 0x00FF80, 0x00FFBF, 0x00FFFF,
  95. 0x0F0F0F, 0x1E1E1E, 0x2D2D2D, 0x330000, 0x330040, 0x330080, 0x3300BF, 0x3300FF, 0x332400, 0x332440, 0x332480, 0x3324BF, 0x3324FF, 0x334900,
  96. 0x334940, 0x334980, 0x3349BF, 0x3349FF, 0x336D00, 0x336D40, 0x336D80, 0x336DBF, 0x336DFF, 0x339200, 0x339240, 0x339280, 0x3392BF, 0x3392FF,
  97. 0x33B600, 0x33B640, 0x33B680, 0x33B6BF, 0x33B6FF, 0x33DB00, 0x33DB40, 0x33DB80, 0x33DBBF, 0x33DBFF, 0x33FF00, 0x33FF40, 0x33FF80, 0x33FFBF,
  98. 0x33FFFF, 0x3C3C3C, 0x4B4B4B, 0x5A5A5A, 0x660000, 0x660040, 0x660080, 0x6600BF, 0x6600FF, 0x662400, 0x662440, 0x662480, 0x6624BF, 0x6624FF,
  99. 0x664900, 0x664940, 0x664980, 0x6649BF, 0x6649FF, 0x666D00, 0x666D40, 0x666D80, 0x666DBF, 0x666DFF, 0x669200, 0x669240, 0x669280, 0x6692BF,
  100. 0x6692FF, 0x66B600, 0x66B640, 0x66B680, 0x66B6BF, 0x66B6FF, 0x66DB00, 0x66DB40, 0x66DB80, 0x66DBBF, 0x66DBFF, 0x66FF00, 0x66FF40, 0x66FF80,
  101. 0x66FFBF, 0x66FFFF, 0x696969, 0x787878, 0x878787, 0x969696, 0x990000, 0x990040, 0x990080, 0x9900BF, 0x9900FF, 0x992400, 0x992440, 0x992480,
  102. 0x9924BF, 0x9924FF, 0x994900, 0x994940, 0x994980, 0x9949BF, 0x9949FF, 0x996D00, 0x996D40, 0x996D80, 0x996DBF, 0x996DFF, 0x999200, 0x999240,
  103. 0x999280, 0x9992BF, 0x9992FF, 0x99B600, 0x99B640, 0x99B680, 0x99B6BF, 0x99B6FF, 0x99DB00, 0x99DB40, 0x99DB80, 0x99DBBF, 0x99DBFF, 0x99FF00,
  104. 0x99FF40, 0x99FF80, 0x99FFBF, 0x99FFFF, 0xA5A5A5, 0xB4B4B4, 0xC3C3C3, 0xCC0000, 0xCC0040, 0xCC0080, 0xCC00BF, 0xCC00FF, 0xCC2400, 0xCC2440,
  105. 0xCC2480, 0xCC24BF, 0xCC24FF, 0xCC4900, 0xCC4940, 0xCC4980, 0xCC49BF, 0xCC49FF, 0xCC6D00, 0xCC6D40, 0xCC6D80, 0xCC6DBF, 0xCC6DFF, 0xCC9200,
  106. 0xCC9240, 0xCC9280, 0xCC92BF, 0xCC92FF, 0xCCB600, 0xCCB640, 0xCCB680, 0xCCB6BF, 0xCCB6FF, 0xCCDB00, 0xCCDB40, 0xCCDB80, 0xCCDBBF, 0xCCDBFF,
  107. 0xCCFF00, 0xCCFF40, 0xCCFF80, 0xCCFFBF, 0xCCFFFF, 0xD2D2D2, 0xE1E1E1, 0xF0F0F0, 0xFF0000, 0xFF0040, 0xFF0080, 0xFF00BF, 0xFF00FF, 0xFF2400,
  108. 0xFF2440, 0xFF2480, 0xFF24BF, 0xFF24FF, 0xFF4900, 0xFF4940, 0xFF4980, 0xFF49BF, 0xFF49FF, 0xFF6D00, 0xFF6D40, 0xFF6D80, 0xFF6DBF, 0xFF6DFF,
  109. 0xFF9200, 0xFF9240, 0xFF9280, 0xFF92BF, 0xFF92FF, 0xFFB600, 0xFFB640, 0xFFB680, 0xFFB6BF, 0xFFB6FF, 0xFFDB00, 0xFFDB40, 0xFFDB80, 0xFFDBBF,
  110. 0xFFDBFF, 0xFFFF00, 0xFFFF40, 0xFFFF80, 0xFFFFBF, 0xFFFFFF}
  111.  
  112. local function to24Bit(color8Bit)
  113.     return palette[color8Bit + 1]
  114. end
  115.  
  116. if computer.getArchitecture and computer.getArchitecture() ~= "Lua 5.2" then
  117.     colorIntegerToRGB, colorRGBToInteger, colorBlend = load([[return function(integerColor)
  118.         return integerColor >> 16, integerColor >> 8 & 0xFF, integerColor & 0xFF
  119.     end,
  120.  
  121.     function(r, g, b)
  122.         return r << 16 | g << 8 | b
  123.     end,
  124.  
  125.     function(color1, color2, transparency)
  126.         local invertedTransparency = 1 - transparency
  127.         return
  128.             ((color2 >> 16) * invertedTransparency + (color1 >> 16) * transparency) // 1.0 << 16 |
  129.             ((color2 >> 8 & 0xFF) * invertedTransparency + (color1 >> 8 & 0xFF) * transparency) // 1.0 << 8 |
  130.             ((color2 & 0xFF) * invertedTransparency + (color1 & 0xFF) * transparency) // 1.0
  131.     end]])()
  132. else
  133.     colorIntegerToRGB = function(integerColor)
  134.         local r = integerColor / 65536
  135.         r = r - r % 1
  136.         local g = (integerColor - r * 65536) / 256
  137.         g = g - g % 1
  138.         return r, g, integerColor - r * 65536 - g * 256
  139.     end
  140.  
  141.     colorRGBToInteger = function(r, g, b)
  142.         return r * 65536 + g * 256 + b
  143.     end
  144.  
  145.     colorBlend = function(color1, color2, transparency)
  146.         local invertedTransparency = 1 - transparency
  147.         local r1, r2 = color1 / 65536, color2 / 65536
  148.         r1, r2 = r1 - r1 % 1, r2 - r2 % 1
  149.         local g1, g2 = (color1 - r1 * 65536) / 256, (color2 - r2 * 65536) / 256
  150.         g1, g2 = g1 - g1 % 1, g2 - g2 % 1
  151.         local r, g, b = r2 * invertedTransparency + r1 * transparency, g2 * invertedTransparency + g1 * transparency,
  152.             (color2 - r2 * 65536 - g2 * 256) * invertedTransparency + (color1 - r1 * 65536 - g1 * 256) * transparency
  153.         return (r - r % 1) * 65536 + (g - g % 1) * 256 + (b - b % 1)
  154.         end
  155. end
  156.  
  157. --------------------------------------------------------------------------------
  158. --AdvancedRead Subsystem (Ported by Bs()Dd)
  159.  
  160. local function readUnicodeChar(file)
  161.     local byteArray = {string.byte(file:read(1))}
  162.  
  163.     local nullBitPosition = 0
  164.     for i = 1, 7 do
  165.         if bit32.band(bit32.rshift(byteArray[1], 8 - i), 0x1) == 0x0 then
  166.             nullBitPosition = i
  167.             break
  168.         end
  169.     end
  170.  
  171.     for i = 1, nullBitPosition - 2 do
  172.         table.insert(byteArray, string.byte(file:read(1)))
  173.     end
  174.  
  175.     return string.char(table.unpack(byteArray))
  176. end
  177.  
  178. local function readBytes(file, count)
  179.     local bytes, result = {string.byte(file:read(count) or "\x00", 1, 8)}, 0
  180.     for i = 1, #bytes do
  181.         result = bit32.bor(bit32.lshift(result, 8), bytes[i])
  182.     end
  183.     return result
  184. end
  185.  
  186. --------------------------------------------------------------------------------
  187. --ImageLoader Subsystem (Ported by Bs0Dd)
  188.  
  189. local function iset(picture, x, y, background, foreground, alpha, symbol)
  190.     local index = 4 * (picture[1] * (y - 1) + x) - 1
  191.     picture[index], picture[index + 1], picture[index + 2], picture[index + 3] = background, foreground, alpha, symbol
  192.     return picture
  193. end
  194.  
  195. local function multiLoad(file, picture, ocif7, ocif8) --MultiLoader for OCIF6-8.
  196.     picture[1] = string.byte(file:read(1)) + ocif8
  197.     picture[2] = string.byte(file:read(1)) + ocif8
  198.  
  199.     local currentAlpha, currentSymbol, currentBackground, currentForeground, currentY
  200.  
  201.     for alpha = 1, string.byte(file:read(1)) + ocif7 do
  202.  
  203.         currentAlpha = string.byte(file:read(1)) / 255
  204.  
  205.         for symbol = 1, readBytes(file, 2) + ocif7 do
  206.             currentSymbol = readUnicodeChar(file)
  207.  
  208.             for background = 1, string.byte(file:read(1)) + ocif7 do
  209.                 currentBackground = to24Bit(string.byte(file:read(1)))
  210.  
  211.                 for foreground = 1, string.byte(file:read(1)) + ocif7 do
  212.                     currentForeground = to24Bit(string.byte(file:read(1)))
  213.  
  214.                     for y = 1, string.byte(file:read(1)) + ocif7 do
  215.                         currentY = string.byte(file:read(1))
  216.  
  217.                         for x = 1, string.byte(file:read(1)) + ocif7 do
  218.                             iset(
  219.                                 picture,
  220.                                 string.byte(file:read(1)) + ocif8,
  221.                                 currentY + ocif8,
  222.                                 currentBackground,
  223.                                 currentForeground,
  224.                                 currentAlpha,
  225.                                 currentSymbol
  226.                             )
  227.                         end
  228.                     end
  229.                 end
  230.             end
  231.         end
  232.     end
  233. end
  234.  
  235. local Loader = {}
  236.  
  237. Loader[5] = function(file, picture)
  238.     picture[1] = readBytes(file, 2)
  239.     picture[2] = readBytes(file, 2)
  240.  
  241.     for i = 1, picture[1] * picture[2] do
  242.         table.insert(picture, to24Bit(string.byte(file:read(1))))
  243.         table.insert(picture, to24Bit(string.byte(file:read(1))))
  244.         table.insert(picture, string.byte(file:read(1)) / 255)
  245.         table.insert(picture, readUnicodeChar(file))
  246.     end
  247. end
  248.  
  249. Loader[6] = function(file, picture)
  250.     multiLoad(file, picture, 0, 0)
  251. end
  252.  
  253. Loader[7] = function(file, picture)
  254.     multiLoad(file, picture, 1, 0)
  255. end
  256.  
  257. Loader[8] = function(file, picture)
  258.     multiLoad(file, picture, 1, 1)
  259. end
  260.  
  261. local function loadImage(path)
  262.     local file, reason = io.open(path, "rb")
  263.  
  264.     if file then
  265.         local readedSignature = file:read(4)
  266.  
  267.         if readedSignature == "OCIF" then
  268.             local encodingMethod = string.byte(file:read(1))
  269.  
  270.             if Loader[encodingMethod] then
  271.                 local picture = {}
  272.                 local result, reason = xpcall(Loader[encodingMethod], debug.traceback, file, picture)
  273.                 file:close()
  274.                 if result then
  275.                     return picture
  276.                 else
  277.                     return false, "Failed to load OCIF image: " .. tostring(reason)
  278.                 end
  279.             else
  280.                 file:close()
  281.                 return false, "Failed to load OCIF image: encoding method \"" .. tostring(encodingMethod) .. "\" is not supported"
  282.             end
  283.         else
  284.             file:close()
  285.             return false, "Failed to load OCIF image: binary signature \"" .. tostring(readedSignature) .. "\" is not valid"
  286.         end
  287.     else
  288.         return false, "Failed to open file \"" .. tostring(path) .. "\" for reading: " .. tostring(reason)
  289.     end
  290. end
  291.  
  292. --------------------------------------------------------------------------------
  293.  
  294. local function flush(width, height)
  295.     if not width or not height then
  296.         width, height = componentInvoke(GPUAddress, "getResolution")
  297.     end
  298.  
  299.     currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols, newFrameBackgrounds, newFrameForegrounds, newFrameSymbols = {}, {}, {}, {}, {}, {}
  300.     bufferWidth = width
  301.     bufferHeight = height
  302.  
  303.     resetDrawLimit()
  304.  
  305.     for i = 1, bufferWidth * bufferHeight do
  306.         currentFrameBackgrounds[i] = 0x010101
  307.         newFrameBackgrounds[i] = 0x010101
  308.  
  309.         currentFrameForegrounds[i] = 0xFEFEFE
  310.         newFrameForegrounds[i] = 0xFEFEFE
  311.  
  312.         currentFrameSymbols[i] = " "
  313.         newFrameSymbols[i] = " "
  314.     end
  315. end
  316.  
  317. local function getGPUAddress()
  318.     return GPUAddress
  319. end
  320.  
  321. local function setGPUAddress(address)
  322.     GPUAddress = address
  323.  
  324.     flush()
  325. end
  326.  
  327. local function getScreenAddress()
  328.     return componentInvoke(GPUAddress, "getScreen")
  329. end
  330.  
  331. local function getMaxResolution()
  332.     return componentInvoke(GPUAddress, "maxResolution")
  333. end
  334.  
  335. local function setResolution(width, height)
  336.     componentInvoke(GPUAddress, "setResolution", width, height)
  337.  
  338.     flush(width, height)
  339. end
  340.  
  341. local function getColorDepth()
  342.     return componentInvoke(GPUAddress, "getDepth")
  343. end
  344.  
  345. local function setColorDepth(...)
  346.     return componentInvoke(GPUAddress, "setDepth", ...)
  347. end
  348.  
  349. local function getMaxColorDepth(...)
  350.     return componentInvoke(GPUAddress, "maxDepth")
  351. end
  352.  
  353. local function getScreenAspectRatio()
  354.     return componentInvoke(getScreenAddress(), "getAspectRatio")
  355. end
  356.  
  357. local function getResolution()
  358.     return bufferWidth, bufferHeight
  359. end
  360.  
  361. local function getWidth()
  362.     return bufferWidth
  363. end
  364.  
  365. local function getHeight()
  366.     return bufferHeight
  367. end
  368.  
  369. local function setScreenAddress(address, reset)
  370.     local success, reason = componentInvoke(GPUAddress, "bind", address, reset)
  371.  
  372.     if success then
  373.         if reset then
  374.             setResolution(getMaxResolution())
  375.         else
  376.             setResolution(bufferWidth, bufferHeight)
  377.         end
  378.     else
  379.         return success, reason
  380.     end
  381. end
  382.  
  383. local function getGPUProxy() --DEPRECATED, for backwards compatibility only
  384.     return component.proxy(GPUAddress or "")
  385. end
  386.  
  387. local function setGPUProxy(proxy)  --DEPRECATED, for backwards compatibility only
  388.     return setGPUAddress(proxy.address)
  389. end
  390.  
  391. local function getScaledResolution(scale)
  392.     if not scale or scale > 1 then
  393.         scale = 1
  394.     elseif scale < 0.1 then
  395.         scale = 0.1
  396.     end
  397.  
  398.     local aspectWidth, aspectHeight = getScreenAspectRatio()
  399.     local maxWidth, maxHeight = getMaxResolution()
  400.     local proportion = 2 * (16 * aspectWidth - 4.5) / (16 * aspectHeight - 4.5)
  401.  
  402.     local height = scale * mathMin(
  403.         maxWidth / proportion,
  404.         maxWidth,
  405.         math.sqrt(maxWidth * maxHeight / proportion)
  406.     )
  407.  
  408.     return math.floor(height * proportion), math.floor(height)
  409. end
  410.  
  411. --------------------------------------------------------------------------------
  412.  
  413. local function rawSet(index, background, foreground, symbol)
  414.     newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
  415. end
  416.  
  417. local function rawGet(index)
  418.     return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  419. end
  420.  
  421. local function get(x, y)
  422.     if x >= 1 and y >= 1 and x <= bufferWidth and y <= bufferHeight then
  423.         local index = bufferWidth * (y - 1) + x
  424.         return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  425.     else
  426.         return 0x000000, 0x000000, " "
  427.     end
  428. end
  429.  
  430. local function set(x, y, background, foreground, symbol)
  431.     if x >= drawLimitX1 and y >= drawLimitY1 and x <= drawLimitX2 and y <= drawLimitY2 then
  432.         local index = bufferWidth * (y - 1) + x
  433.         newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
  434.     end
  435. end
  436.  
  437. local function drawRectangle(x, y, width, height, background, foreground, symbol, transparency)
  438.     local temp
  439.  
  440.     -- Clipping left
  441.     if x < drawLimitX1 then
  442.         width = width - drawLimitX1 + x
  443.         x = drawLimitX1
  444.     end
  445.  
  446.     -- Right
  447.     temp = x + width - 1
  448.     if temp > drawLimitX2 then
  449.         width = width - temp + drawLimitX2
  450.     end
  451.  
  452.     -- Top
  453.     if y < drawLimitY1 then
  454.         height = height - drawLimitY1 + y
  455.         y = drawLimitY1
  456.     end
  457.  
  458.     -- Bottom
  459.     temp = y + height - 1
  460.     if temp > drawLimitY2 then
  461.         height = height - temp + drawLimitY2
  462.     end
  463.  
  464.     temp = bufferWidth * (y - 1) + x
  465.  
  466.     local indexStepOnEveryLine = bufferWidth - width
  467.  
  468.     if transparency then
  469.         for j = 1, height do
  470.             for i = 1, width do
  471.                 newFrameBackgrounds[temp],
  472.                 newFrameForegrounds[temp] =
  473.                     colorBlend(newFrameBackgrounds[temp], background, transparency),
  474.                     colorBlend(newFrameForegrounds[temp], background, transparency)
  475.  
  476.                 temp = temp + 1
  477.             end
  478.  
  479.             temp = temp + indexStepOnEveryLine
  480.         end
  481.     else
  482.         for j = 1, height do
  483.             for i = 1, width do
  484.                 newFrameBackgrounds[temp],
  485.                 newFrameForegrounds[temp],
  486.                 newFrameSymbols[temp] = background, foreground, symbol
  487.  
  488.                 temp = temp + 1
  489.             end
  490.  
  491.             temp = temp + indexStepOnEveryLine
  492.         end
  493.     end
  494. end
  495.  
  496. local function blur(x, y, width, height, radius, color, transparency)
  497.     local temp
  498.  
  499.     -- Clipping left
  500.     if x < drawLimitX1 then
  501.         width = width - drawLimitX1 + x
  502.         x = drawLimitX1
  503.     end
  504.  
  505.     -- Right
  506.     temp = x + width - 1
  507.     if temp > drawLimitX2 then
  508.         width = width - temp + drawLimitX2
  509.     end
  510.  
  511.     -- Top
  512.     if y < drawLimitY1 then
  513.         height = height - drawLimitY1 + y
  514.         y = drawLimitY1
  515.     end
  516.  
  517.     -- Bottom
  518.     temp = y + height - 1
  519.     if temp > drawLimitY2 then
  520.         height = height - temp + drawLimitY2
  521.     end
  522.  
  523.     local screenIndex, indexStepOnEveryLine, buffer, bufferIndex, rSum, gSum, bSum, rSumFg, gSumFg, bSumFg, r, g, b =
  524.         bufferWidth * (y - 1) + x,
  525.         bufferWidth - width,
  526.         {},
  527.         1
  528.  
  529.     -- Copying
  530.     temp = screenIndex
  531.  
  532.     if color then
  533.         for j = 1, height do
  534.             for i = 1, width do
  535.                 buffer[bufferIndex] = colorBlend(newFrameBackgrounds[temp], color, transparency)
  536.  
  537.                 temp, bufferIndex = temp + 1, bufferIndex + 1
  538.             end
  539.  
  540.             temp = temp + indexStepOnEveryLine
  541.         end
  542. else
  543.         for j = 1, height do
  544.             for i = 1, width do
  545.                 buffer[bufferIndex] = newFrameBackgrounds[temp]
  546.  
  547.                 temp, bufferIndex = temp + 1, bufferIndex + 1
  548.             end
  549.  
  550.             temp = temp + indexStepOnEveryLine
  551.         end
  552.     end
  553.  
  554.     -- Blurring
  555.     local rSum, gSum, bSum, count, r, g, b
  556.  
  557.     for j = 1, height do
  558.         for i = 1, width do
  559.             rSum, gSum, bSum, count = 0, 0, 0, 0
  560.  
  561.             for jr = mathMax(1, j - radius), mathMin(j + radius, height) do
  562.                 for ir = mathMax(1, i - radius), mathMin(i + radius, width) do
  563.                     r, g, b = colorIntegerToRGB(buffer[width * (jr - 1) + ir])
  564.                     rSum, gSum, bSum, count = rSum + r, gSum + g, bSum + b, count + 1
  565.                 end
  566.             end
  567.  
  568.             -- Calculatin average channels value
  569.             r, g, b = rSum / count, gSum / count, bSum / count
  570.             -- Faster than math.floor
  571.             r, g, b = r - r % 1, g - g % 1, b - b % 1
  572.  
  573.             newFrameBackgrounds[screenIndex] = colorRGBToInteger(r, g, b)
  574.             newFrameForegrounds[screenIndex] = 0x0
  575.             newFrameSymbols[screenIndex] = " "
  576.  
  577.             screenIndex = screenIndex + 1
  578.         end
  579.  
  580.         screenIndex = screenIndex + indexStepOnEveryLine
  581.     end
  582. end
  583.  
  584. local function clear(color, transparency)
  585.     drawRectangle(1, 1, bufferWidth, bufferHeight, color or 0x0, 0x000000, " ", transparency)
  586. end
  587.  
  588. local function copy(x, y, width, height)
  589.     local copyArray, index = { width, height }
  590.  
  591.     for j = y, y + height - 1 do
  592.         for i = x, x + width - 1 do
  593.             if i >= 1 and j >= 1 and i <= bufferWidth and j <= bufferHeight then
  594.                 index = bufferWidth * (j - 1) + i
  595.                 tableInsert(copyArray, newFrameBackgrounds[index])
  596.                 tableInsert(copyArray, newFrameForegrounds[index])
  597.                 tableInsert(copyArray, newFrameSymbols[index])
  598.             else
  599.                 tableInsert(copyArray, 0x0)
  600.                 tableInsert(copyArray, 0x0)
  601.                 tableInsert(copyArray, " ")
  602.             end
  603.         end
  604.     end
  605.  
  606.     return copyArray
  607. end
  608.  
  609. local function paste(startX, startY, picture)
  610.     local imageWidth = picture[1]
  611.     local screenIndex, pictureIndex, screenIndexStepOnReachOfImageWidth = bufferWidth * (startY - 1) + startX, 3, bufferWidth - imageWidth
  612.  
  613.     for y = startY, startY + picture[2] - 1 do
  614.         if y >= drawLimitY1 and y <= drawLimitY2 then
  615.             for x = startX, startX + imageWidth - 1 do
  616.                 if x >= drawLimitX1 and x <= drawLimitX2 then
  617.                     newFrameBackgrounds[screenIndex] = picture[pictureIndex]
  618.                     newFrameForegrounds[screenIndex] = picture[pictureIndex + 1]
  619.                     newFrameSymbols[screenIndex] = picture[pictureIndex + 2]
  620.                 end
  621.  
  622.                 screenIndex, pictureIndex = screenIndex + 1, pictureIndex + 3
  623.             end
  624.  
  625.             screenIndex = screenIndex + screenIndexStepOnReachOfImageWidth
  626.         else
  627.             screenIndex, pictureIndex = screenIndex + bufferWidth, pictureIndex + imageWidth * 3
  628.         end
  629.     end
  630. end
  631.  
  632. local function rasterizeLine(x1, y1, x2, y2, method)
  633.     local inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = x1, x2, y1, y2, false, mathAbs(x2 - x1), mathAbs(y2 - y1)
  634.     if inLoopValueDelta < outLoopValueDelta then
  635.         inLoopValueFrom, inLoopValueTo, outLoopValueFrom, outLoopValueTo, isReversed, inLoopValueDelta, outLoopValueDelta = y1, y2, x1, x2, true, outLoopValueDelta, inLoopValueDelta
  636.     end
  637.  
  638.     if outLoopValueFrom > outLoopValueTo then
  639.         outLoopValueFrom, outLoopValueTo = outLoopValueTo, outLoopValueFrom
  640.         inLoopValueFrom, inLoopValueTo = inLoopValueTo, inLoopValueFrom
  641.     end
  642.  
  643.     local outLoopValue, outLoopValueCounter, outLoopValueTriggerIncrement = outLoopValueFrom, 1, inLoopValueDelta / outLoopValueDelta
  644.     local outLoopValueTrigger = outLoopValueTriggerIncrement
  645.  
  646.     for inLoopValue = inLoopValueFrom, inLoopValueTo, inLoopValueFrom < inLoopValueTo and 1 or -1 do
  647.         if isReversed then
  648.             method(outLoopValue, inLoopValue)
  649.         else
  650.             method(inLoopValue, outLoopValue)
  651.         end
  652.  
  653.         outLoopValueCounter = outLoopValueCounter + 1
  654.         if outLoopValueCounter > outLoopValueTrigger then
  655.             outLoopValue, outLoopValueTrigger = outLoopValue + 1, outLoopValueTrigger + outLoopValueTriggerIncrement
  656.         end
  657.     end
  658. end
  659.  
  660. local function rasterizeEllipse(centerX, centerY, radiusX, radiusY, method)
  661.     local function rasterizeEllipsePoints(XP, YP)
  662.         method(centerX + XP, centerY + YP)
  663.         method(centerX - XP, centerY + YP)
  664.         method(centerX - XP, centerY - YP)
  665.         method(centerX + XP, centerY - YP)
  666.     end
  667.  
  668.     local x, y, changeX, changeY, ellipseError, twoASquare, twoBSquare = radiusX, 0, radiusY * radiusY * (1 - 2 * radiusX), radiusX * radiusX, 0, 2 * radiusX * radiusX, 2 * radiusY * radiusY
  669.     local stoppingX, stoppingY = twoBSquare * radiusX, 0
  670.  
  671.     while stoppingX >= stoppingY do
  672.         rasterizeEllipsePoints(x, y)
  673.  
  674.         y, stoppingY, ellipseError = y + 1, stoppingY + twoASquare, ellipseError + changeY
  675.         changeY = changeY + twoASquare
  676.  
  677.         if (2 * ellipseError + changeX) > 0 then
  678.             x, stoppingX, ellipseError = x - 1, stoppingX - twoBSquare, ellipseError + changeX
  679.             changeX = changeX + twoBSquare
  680.         end
  681.     end
  682.  
  683.     x, y, changeX, changeY, ellipseError, stoppingX, stoppingY = 0, radiusY, radiusY * radiusY, radiusX * radiusX * (1 - 2 * radiusY), 0, 0, twoASquare * radiusY
  684.  
  685.     while stoppingX <= stoppingY do
  686.         rasterizeEllipsePoints(x, y)
  687.  
  688.         x, stoppingX, ellipseError = x + 1, stoppingX + twoBSquare, ellipseError + changeX
  689.         changeX = changeX + twoBSquare
  690.  
  691.         if (2 * ellipseError + changeY) > 0 then
  692.             y, stoppingY, ellipseError = y - 1, stoppingY - twoASquare, ellipseError + changeY
  693.             changeY = changeY + twoASquare
  694.         end
  695.     end
  696. end
  697.  
  698. local function rasterizePolygon(centerX, centerY, startX, startY, countOfEdges, method)
  699.     local degreeStep = 360 / countOfEdges
  700.  
  701.     local deltaX, deltaY = startX - centerX, startY - centerY
  702.     local radius = math.sqrt(deltaX ^ 2 + deltaY ^ 2)
  703.     local halfRadius = radius / 2
  704.     local startDegree = math.deg(math.asin(deltaX / radius))
  705.  
  706.     local function round(num)
  707.         if num >= 0 then
  708.             return math.floor(num + 0.5)
  709.         else
  710.             return math.ceil(num - 0.5)
  711.         end
  712.     end
  713.  
  714.     local function calculatePosition(degree)
  715.         local radDegree = math.rad(degree)
  716.         local deltaX2 = math.sin(radDegree) * radius
  717.         local deltaY2 = math.cos(radDegree) * radius
  718.  
  719.         return round(centerX + deltaX2), round(centerY + (deltaY >= 0 and deltaY2 or -deltaY2))
  720.     end
  721.  
  722.     local xOld, yOld, xNew, yNew = calculatePosition(startDegree)
  723.  
  724.     for degree = (startDegree + degreeStep - 1), (startDegree + 360), degreeStep do
  725.         xNew, yNew = calculatePosition(degree)
  726.         rasterizeLine(xOld, yOld, xNew, yNew, method)
  727.         xOld, yOld = xNew, yNew
  728.     end
  729. end
  730.  
  731. local function drawLine(x1, y1, x2, y2, background, foreground, symbol)
  732.     rasterizeLine(x1, y1, x2, y2, function(x, y)
  733.         set(x, y, background, foreground, symbol)
  734.     end)
  735. end
  736.  
  737. local function drawEllipse(centerX, centerY, radiusX, radiusY, background, foreground, symbol)
  738.     rasterizeEllipse(centerX, centerY, radiusX, radiusY, function(x, y)
  739.         set(x, y, background, foreground, symbol)
  740.     end)
  741. end
  742.  
  743. local function drawPolygon(centerX, centerY, radiusX, radiusY, background, foreground, countOfEdges, symbol)
  744.     rasterizePolygon(centerX, centerY, radiusX, radiusY, countOfEdges, function(x, y)
  745.         set(x, y, background, foreground, symbol)
  746.     end)
  747. end
  748.  
  749. local function drawText(x, y, textColor, data, transparency)
  750.     if y >= drawLimitY1 and y <= drawLimitY2 then
  751.         local charIndex, screenIndex = 1, bufferWidth * (y - 1) + x
  752.  
  753.         for charIndex = 1, unicodeLen(data) do
  754.             if x >= drawLimitX1 and x <= drawLimitX2 then
  755.                 if transparency then
  756.                     newFrameForegrounds[screenIndex] = colorBlend(newFrameBackgrounds[screenIndex], textColor, transparency)
  757.                 else
  758.                     newFrameForegrounds[screenIndex] = textColor
  759.                 end
  760.  
  761.                 newFrameSymbols[screenIndex] = unicodeSub(data, charIndex, charIndex)
  762.             end
  763.  
  764.             x, screenIndex = x + 1, screenIndex + 1
  765.         end
  766.     end
  767. end
  768.  
  769. local function drawImage(x, y, picture, blendForeground)
  770.     local imageWidth, imageHeight, pictureIndex, temp = picture[1], picture[2], 3
  771.     local clippedImageWidth, clippedImageHeight = imageWidth, imageHeight
  772.  
  773.     -- Clipping left
  774.     if x < drawLimitX1 then
  775.         temp = drawLimitX1 - x
  776.         clippedImageWidth, x, pictureIndex = clippedImageWidth - temp, drawLimitX1, pictureIndex + temp * 4
  777.     end
  778.  
  779.     -- Right
  780.     temp = x + clippedImageWidth - 1
  781.  
  782.     if temp > drawLimitX2 then
  783.         clippedImageWidth = clippedImageWidth - temp + drawLimitX2
  784.     end
  785.  
  786.     -- Top
  787.     if y < drawLimitY1 then
  788.         temp = drawLimitY1 - y
  789.         clippedImageHeight, y, pictureIndex = clippedImageHeight - temp, drawLimitY1, pictureIndex + temp * imageWidth * 4
  790.     end
  791.  
  792.     -- Bottom
  793.     temp = y + clippedImageHeight - 1
  794.  
  795.     if temp > drawLimitY2 then
  796.         clippedImageHeight = clippedImageHeight - temp + drawLimitY2
  797.     end
  798.  
  799.     local
  800.         screenIndex,
  801.         screenIndexStep,
  802.         pictureIndexStep,
  803.         background,
  804.         foreground,
  805.         alpha,
  806.         symbol = bufferWidth * (y - 1) + x, bufferWidth - clippedImageWidth, (imageWidth - clippedImageWidth) * 4
  807.  
  808.     for j = 1, clippedImageHeight do
  809.         for i = 1, clippedImageWidth do
  810.             alpha, symbol = picture[pictureIndex + 2], picture[pictureIndex + 3]
  811.  
  812.             -- If it's fully transparent pixel
  813.             if alpha == 0 then
  814.                 newFrameBackgrounds[screenIndex], newFrameForegrounds[screenIndex] = picture[pictureIndex], picture[pictureIndex + 1]
  815.             -- If it has some transparency
  816.             elseif alpha > 0 and alpha < 1 then
  817.                 newFrameBackgrounds[screenIndex] = colorBlend(newFrameBackgrounds[screenIndex], picture[pictureIndex], alpha)
  818.  
  819.                 if blendForeground then
  820.                     newFrameForegrounds[screenIndex] = colorBlend(newFrameForegrounds[screenIndex], picture[pictureIndex + 1], alpha)
  821.                 else
  822.                     newFrameForegrounds[screenIndex] = picture[pictureIndex + 1]
  823.                 end
  824.             -- If it's not transparent with whitespace
  825.             elseif symbol ~= " " then
  826.                 newFrameForegrounds[screenIndex] = picture[pictureIndex + 1]
  827.             end
  828.  
  829.             newFrameSymbols[screenIndex] = symbol
  830.  
  831.             screenIndex, pictureIndex = screenIndex + 1, pictureIndex + 4
  832.         end
  833.  
  834.         screenIndex, pictureIndex = screenIndex + screenIndexStep, pictureIndex + pictureIndexStep
  835.     end
  836. end
  837.  
  838. local function drawFrame(x, y, width, height, color)
  839.     local stringUp, stringDown, x2 = "┌" .. string.rep("─", width - 2) .. "┐", "└" .. string.rep("─", width - 2) .. "┘", x + width - 1
  840.  
  841.     drawText(x, y, color, stringUp); y = y + 1
  842.     for i = 1, height - 2 do
  843.         drawText(x, y, color, "│")
  844.         drawText(x2, y, color, "│")
  845.         y = y + 1
  846.     end
  847.     drawText(x, y, color, stringDown)
  848. end
  849.  
  850. --------------------------------------------------------------------------------
  851.  
  852. local function semiPixelRawSet(index, color, yPercentTwoEqualsZero)
  853.     local upperPixel, lowerPixel, bothPixel = "▀", "▄", " "
  854.     local background, foreground, symbol = newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  855.  
  856.     if yPercentTwoEqualsZero then
  857.         if symbol == upperPixel then
  858.             if color == foreground then
  859.                 newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, bothPixel
  860.             else
  861.                 newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, symbol
  862.             end
  863.         elseif symbol == bothPixel then
  864.             if color ~= background then
  865.                 newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, lowerPixel
  866.             end
  867.         else
  868.             newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, lowerPixel
  869.         end
  870.     else
  871.         if symbol == lowerPixel then
  872.             if color == foreground then
  873.                 newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, bothPixel
  874.             else
  875.                 newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = color, foreground, symbol
  876.             end
  877.         elseif symbol == bothPixel then
  878.             if color ~= background then
  879.                 newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, upperPixel
  880.             end
  881.         else
  882.             newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, color, upperPixel
  883.         end
  884.     end
  885. end
  886.  
  887. local function semiPixelSet(x, y, color)
  888.     local yFixed = mathCeil(y / 2)
  889.     if x >= drawLimitX1 and yFixed >= drawLimitY1 and x <= drawLimitX2 and yFixed <= drawLimitY2 then
  890.         semiPixelRawSet(bufferWidth * (yFixed - 1) + x, color, y % 2 == 0)
  891.     end
  892. end
  893.  
  894. local function drawSemiPixelRectangle(x, y, width, height, color)
  895.     local index, evenYIndexStep, oddYIndexStep, realY, evenY =
  896.         bufferWidth * (mathCeil(y / 2) - 1) + x,
  897.         (bufferWidth - width),
  898.         width
  899.  
  900.     for pseudoY = y, y + height - 1 do
  901.         realY = mathCeil(pseudoY / 2)
  902.  
  903.         if realY >= drawLimitY1 and realY <= drawLimitY2 then
  904.             evenY = pseudoY % 2 == 0
  905.  
  906.             for pseudoX = x, x + width - 1 do
  907.                 if pseudoX >= drawLimitX1 and pseudoX <= drawLimitX2 then
  908.                     semiPixelRawSet(index, color, evenY)
  909.                 end
  910.  
  911.                 index = index + 1
  912.             end
  913.         else
  914.             index = index + width
  915.         end
  916.  
  917.         if evenY then
  918.             index = index + evenYIndexStep
  919.         else
  920.             index = index - oddYIndexStep
  921.         end
  922.     end
  923. end
  924.  
  925. local function drawSemiPixelLine(x1, y1, x2, y2, color)
  926.     rasterizeLine(x1, y1, x2, y2, function(x, y)
  927.         semiPixelSet(x, y, color)
  928.     end)
  929. end
  930.  
  931. local function drawSemiPixelEllipse(centerX, centerY, radiusX, radiusY, color)
  932.     rasterizeEllipse(centerX, centerY, radiusX, radiusY, function(x, y)
  933.         semiPixelSet(x, y, color)
  934.     end)
  935. end
  936.  
  937. --------------------------------------------------------------------------------
  938.  
  939. local function getPointTimedPosition(firstPoint, secondPoint, time)
  940.     return {
  941.         x = firstPoint.x + (secondPoint.x - firstPoint.x) * time,
  942.         y = firstPoint.y + (secondPoint.y - firstPoint.y) * time
  943.     }
  944. end
  945.  
  946. local function getConnectionPoints(points, time)
  947.     local connectionPoints = {}
  948.  
  949.     for point = 1, #points - 1 do
  950.         tableInsert(connectionPoints, getPointTimedPosition(points[point], points[point + 1], time))
  951.     end
  952.  
  953.     return connectionPoints
  954. end
  955.  
  956. local function getMainPointPosition(points, time)
  957.     if #points > 1 then
  958.         return getMainPointPosition(getConnectionPoints(points, time), time)
  959.     else
  960.         return points[1]
  961.     end
  962. end
  963.  
  964. local function drawSemiPixelCurve(points, color, precision)
  965.     local linePoints = {}
  966.  
  967.     for time = 0, 1, precision or 0.01 do
  968.         tableInsert(linePoints, getMainPointPosition(points, time))
  969.     end
  970.  
  971.     for point = 1, #linePoints - 1 do
  972.         drawSemiPixelLine(mathFloor(linePoints[point].x), mathFloor(linePoints[point].y), mathFloor(linePoints[point + 1].x), mathFloor(linePoints[point + 1].y), color)
  973.     end
  974. end
  975.  
  976. --------------------------------------------------------------------------------
  977.  
  978. local function update(force)
  979.     local index, indexStepOnEveryLine, changes = bufferWidth * (drawLimitY1 - 1) + drawLimitX1, (bufferWidth - drawLimitX2 + drawLimitX1 - 1), {}
  980.     local x, equalChars, equalCharsIndex, charX, charIndex, currentForeground
  981.     local currentFrameBackground, currentFrameForeground, currentFrameSymbol, changesCurrentFrameBackground, changesCurrentFrameBackgroundCurrentFrameForeground
  982.  
  983.     local changesCurrentFrameBackgroundCurrentFrameForegroundIndex
  984.  
  985.     for y = drawLimitY1, drawLimitY2 do
  986.         x = drawLimitX1
  987.  
  988.         while x <= drawLimitX2 do
  989.             -- Determine if some pixel data was changed (or if <force> argument was passed)
  990.             if
  991.                 currentFrameBackgrounds[index] ~= newFrameBackgrounds[index] or
  992.                 currentFrameForegrounds[index] ~= newFrameForegrounds[index] or
  993.                 currentFrameSymbols[index] ~= newFrameSymbols[index] or
  994.                 force
  995.             then
  996.                 -- Make pixel at both frames equal
  997.                 currentFrameBackground, currentFrameForeground, currentFrameSymbol = newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
  998.                 currentFrameBackgrounds[index] = currentFrameBackground
  999.                 currentFrameForegrounds[index] = currentFrameForeground
  1000.                 currentFrameSymbols[index] = currentFrameSymbol
  1001.  
  1002.                 -- Look for pixels with equal chars from right of current pixel
  1003.                 equalChars, equalCharsIndex, charX, charIndex = {currentFrameSymbol}, 2, x + 1, index + 1
  1004.  
  1005.                 while charX <= drawLimitX2 do
  1006.                     -- Pixels becomes equal only if they have same background and (whitespace char or same foreground)
  1007.                     if
  1008.                         currentFrameBackground == newFrameBackgrounds[charIndex] and
  1009.                         (
  1010.                             newFrameSymbols[charIndex] == " " or
  1011.                             currentFrameForeground == newFrameForegrounds[charIndex]
  1012.                         )
  1013.                     then
  1014.                         -- Make pixel at both frames equal
  1015.                         currentFrameBackgrounds[charIndex] = newFrameBackgrounds[charIndex]
  1016.                         currentFrameForegrounds[charIndex] = newFrameForegrounds[charIndex]
  1017.                         currentFrameSymbols[charIndex] = newFrameSymbols[charIndex]
  1018.  
  1019.                         equalChars[equalCharsIndex], equalCharsIndex = currentFrameSymbols[charIndex], equalCharsIndex + 1
  1020.                     else
  1021.                         break
  1022.                     end
  1023.  
  1024.                     charX, charIndex = charX + 1, charIndex + 1
  1025.                 end
  1026.  
  1027.                 -- Group pixels that need to be drawn by background and foreground
  1028.                 changesCurrentFrameBackground = changes[currentFrameBackground] or {}
  1029.                 changes[currentFrameBackground] = changesCurrentFrameBackground
  1030.                 changesCurrentFrameBackgroundCurrentFrameForeground = changesCurrentFrameBackground[currentFrameForeground] or {index = 1}
  1031.                 changesCurrentFrameBackground[currentFrameForeground] = changesCurrentFrameBackgroundCurrentFrameForeground
  1032.  
  1033.                 changesCurrentFrameBackgroundCurrentFrameForegroundIndex = changesCurrentFrameBackgroundCurrentFrameForeground.index
  1034.                 changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = x, changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  1035.                 changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = y, changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  1036.                 changesCurrentFrameBackgroundCurrentFrameForeground[changesCurrentFrameBackgroundCurrentFrameForegroundIndex], changesCurrentFrameBackgroundCurrentFrameForegroundIndex = tableConcat(equalChars), changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
  1037.  
  1038.                 x, index, changesCurrentFrameBackgroundCurrentFrameForeground.index = x + equalCharsIndex - 2, index + equalCharsIndex - 2, changesCurrentFrameBackgroundCurrentFrameForegroundIndex
  1039.             end
  1040.  
  1041.             x, index = x + 1, index + 1
  1042.         end
  1043.  
  1044.         index = index + indexStepOnEveryLine
  1045.     end
  1046.  
  1047.     -- Draw grouped pixels on screen
  1048.     for background, foregrounds in pairs(changes) do
  1049.         componentInvoke(GPUAddress, "setBackground", background)
  1050.  
  1051.         for foreground, pixels in pairs(foregrounds) do
  1052.             if currentForeground ~= foreground then
  1053.                 componentInvoke(GPUAddress, "setForeground", foreground)
  1054.                 currentForeground = foreground
  1055.             end
  1056.  
  1057.             for i = 1, #pixels, 3 do
  1058.                 componentInvoke(GPUAddress, "set", pixels[i], pixels[i + 1], pixels[i + 2])
  1059.             end
  1060.         end
  1061.     end
  1062.  
  1063.     changes = nil
  1064. end
  1065.  
  1066. --------------------------------------------------------------------------------
  1067.  
  1068. return {
  1069.     loadImage = loadImage,
  1070.  
  1071.     getIndex = getIndex,
  1072.     setDrawLimit = setDrawLimit,
  1073.     resetDrawLimit = resetDrawLimit,
  1074.     getDrawLimit = getDrawLimit,
  1075.     flush = flush,
  1076.  
  1077.     setResolution = setResolution,
  1078.     getMaxResolution = getMaxResolution,
  1079.  
  1080.     bind = setScreenAddress, --DEPRECATED, for backwards compatibility only
  1081.     setGPUProxy = setGPUProxy, --DEPRECATED, for backwards compatibility only
  1082.     getGPUProxy = getGPUProxy, --DEPRECATED, for backwards compatibility only
  1083.  
  1084.     setGPUAddress = setGPUAddress,
  1085.     getGPUAddress = getGPUAddress,
  1086.     setScreenAddress = setScreenAddress,
  1087.  
  1088.     getColorDepth = getColorDepth,
  1089.     setColorDepth = setColorDepth,
  1090.     getMaxColorDepth = getMaxColorDepth,
  1091.  
  1092.     getScaledResolution = getScaledResolution,
  1093.     getResolution = getResolution,
  1094.     getWidth = getWidth,
  1095.     getHeight = getHeight,
  1096.     getCurrentFrameTables = getCurrentFrameTables,
  1097.     getNewFrameTables = getNewFrameTables,
  1098.  
  1099.     getScreenAspectRatio = getScreenAspectRatio,
  1100.     getScreenAddress = getScreenAddress,
  1101.  
  1102.     rawSet = rawSet,
  1103.     rawGet = rawGet,
  1104.     get = get,
  1105.     set = set,
  1106.     clear = clear,
  1107.     copy = copy,
  1108.     paste = paste,
  1109.     rasterizeLine = rasterizeLine,
  1110.     rasterizeEllipse = rasterizeEllipse,
  1111.     rasterizePolygon = rasterizePolygon,
  1112.     semiPixelRawSet = semiPixelRawSet,
  1113.     semiPixelSet = semiPixelSet,
  1114.     update = update,
  1115.  
  1116.     drawRectangle = drawRectangle,
  1117.     drawLine = drawLine,
  1118.     drawEllipse = drawEllipse,
  1119.     drawPolygon = drawPolygon,
  1120.     drawText = drawText,
  1121.     drawImage = drawImage,
  1122.     drawFrame = drawFrame,
  1123.     blur = blur,
  1124.  
  1125.     drawSemiPixelRectangle = drawSemiPixelRectangle,
  1126.     drawSemiPixelLine = drawSemiPixelLine,
  1127.     drawSemiPixelEllipse = drawSemiPixelEllipse,
  1128.     drawSemiPixelCurve = drawSemiPixelCurve,
  1129. }
  1130.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement