mirror of
https://github.com/S4mpsa/InfOS.git
synced 2025-08-03 18:06:04 -04:00
Adding gui stub
This commit is contained in:
parent
3f887c295a
commit
69d3cf09aa
795
Libraries/graphics/doubleBuffering.lua
Normal file
795
Libraries/graphics/doubleBuffering.lua
Normal file
@ -0,0 +1,795 @@
|
||||
local component = require("component")
|
||||
local unicode = require("unicode")
|
||||
Computer = require("computer")
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local bufferWidth, bufferHeight
|
||||
local currentFrameBackgrounds,
|
||||
currentFrameForegrounds,
|
||||
currentFrameSymbols,
|
||||
newFrameBackgrounds,
|
||||
newFrameForegrounds,
|
||||
newFrameSymbols
|
||||
local drawLimitX1, drawLimitX2, drawLimitY1, drawLimitY2
|
||||
local GPUProxy,
|
||||
GPUProxyGetResolution,
|
||||
GPUProxySetResolution,
|
||||
GPUProxyBind,
|
||||
GPUProxySetBackground,
|
||||
GPUProxySetForeground,
|
||||
GPUProxySet
|
||||
|
||||
local mathCeil, mathFloor, mathAbs = math.ceil, math.floor, math.abs
|
||||
local tableInsert, tableConcat = table.insert, table.concat
|
||||
local colorBlend
|
||||
if Computer.getArchitecture and Computer.getArchitecture() == "Lua 5.3" then
|
||||
colorBlend = load([[function(color1, color2, transparency)
|
||||
local invertedTransparency = 1 - transparency
|
||||
return ((color2 >> 16) * invertedTransparency + (color1 >> 16) * transparency) // 1 << 16 |
|
||||
((color2 >> 8 & 0xFF) * invertedTransparency + (color1 >> 8 & 0xFF) * transparency) // 1 << 8 |
|
||||
((color2 & 0xFF) * invertedTransparency + (color1 & 0xFF) * transparency) // 1
|
||||
end]])
|
||||
else
|
||||
colorBlend = load([[function(color1, color2, transparency)
|
||||
local invertedTransparency = 1 - transparency
|
||||
|
||||
local r1 = color1 / 65536
|
||||
r1 = r1 - r1 % 1
|
||||
local g1 = (color1 - r1 * 65536) / 256
|
||||
g1 = g1 - g1 % 1
|
||||
|
||||
local r2 = color2 / 65536
|
||||
r2 = r2 - r2 % 1
|
||||
local g2 = (color2 - r2 * 65536) / 256
|
||||
g2 = g2 - g2 % 1
|
||||
|
||||
local r, g, b =
|
||||
r2 * invertedTransparency + r1 * transparency,
|
||||
g2 * invertedTransparency + g1 * transparency,
|
||||
(color2 - r2 * 65536 - g2 * 256) * invertedTransparency + (color1 - r1 * 65536 - g1 * 256) * transparency
|
||||
|
||||
return (r - r % 1) * 65536 + (g - g % 1) * 256 + (b - b % 1)
|
||||
end]])
|
||||
end
|
||||
local unicodeLen, unicodeSub = unicode.len, unicode.sub
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function getIndex(x, y)
|
||||
return bufferWidth * (y - 1) + x
|
||||
end
|
||||
|
||||
local function getCurrentFrameTables()
|
||||
return currentFrameBackgrounds, currentFrameForegrounds, currentFrameSymbols
|
||||
end
|
||||
|
||||
local function getNewFrameTables()
|
||||
return newFrameBackgrounds, newFrameForegrounds, newFrameSymbols
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function setDrawLimit(x1, y1, x2, y2)
|
||||
drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = x1, y1, x2, y2
|
||||
end
|
||||
|
||||
local function resetDrawLimit()
|
||||
drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2 = 1, 1, bufferWidth, bufferHeight
|
||||
end
|
||||
|
||||
local function getDrawLimit()
|
||||
return drawLimitX1, drawLimitY1, drawLimitX2, drawLimitY2
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function flush(width, height)
|
||||
if not width or not height then
|
||||
width, height = GPUProxyGetResolution()
|
||||
end
|
||||
|
||||
currentFrameBackgrounds,
|
||||
currentFrameForegrounds,
|
||||
currentFrameSymbols,
|
||||
newFrameBackgrounds,
|
||||
newFrameForegrounds,
|
||||
newFrameSymbols = {}, {}, {}, {}, {}, {}
|
||||
bufferWidth = width
|
||||
bufferHeight = height
|
||||
resetDrawLimit()
|
||||
|
||||
for y = 1, bufferHeight do
|
||||
for x = 1, bufferWidth do
|
||||
tableInsert(currentFrameBackgrounds, 0x010101)
|
||||
tableInsert(currentFrameForegrounds, 0xFEFEFE)
|
||||
tableInsert(currentFrameSymbols, " ")
|
||||
|
||||
tableInsert(newFrameBackgrounds, 0x010101)
|
||||
tableInsert(newFrameForegrounds, 0xFEFEFE)
|
||||
tableInsert(newFrameSymbols, " ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function setResolution(width, height)
|
||||
GPUProxySetResolution(width, height)
|
||||
flush(width, height)
|
||||
end
|
||||
|
||||
local function getResolution()
|
||||
return bufferWidth, bufferHeight
|
||||
end
|
||||
|
||||
local function getWidth()
|
||||
return bufferWidth
|
||||
end
|
||||
|
||||
local function getHeight()
|
||||
return bufferHeight
|
||||
end
|
||||
|
||||
local function bindScreen(...)
|
||||
GPUProxyBind(...)
|
||||
flush(GPUProxyGetResolution())
|
||||
end
|
||||
|
||||
local function getGPUProxy()
|
||||
return GPUProxy
|
||||
end
|
||||
|
||||
local function updateGPUProxyMethods()
|
||||
GPUProxyGet = GPUProxy.get
|
||||
GPUProxyGetResolution = GPUProxy.getResolution
|
||||
GPUProxyGetBackground = GPUProxy.getBackground
|
||||
GPUProxyGetForeground = GPUProxy.getForeground
|
||||
|
||||
GPUProxySet = GPUProxy.set
|
||||
GPUProxySetResolution = GPUProxy.setResolution
|
||||
GPUProxySetBackground = GPUProxy.setBackground
|
||||
GPUProxySetForeground = GPUProxy.setForeground
|
||||
|
||||
GPUProxyBind = GPUProxy.bind
|
||||
GPUProxyFill = GPUProxy.fill
|
||||
end
|
||||
|
||||
local function bindGPU(address)
|
||||
GPUProxy = component.proxy(address)
|
||||
updateGPUProxyMethods()
|
||||
flush(GPUProxyGetResolution())
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function rawSet(index, background, foreground, symbol)
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
|
||||
end
|
||||
|
||||
local function rawGet(index)
|
||||
return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
|
||||
end
|
||||
|
||||
local function get(x, y)
|
||||
if x >= 1 and y >= 1 and x <= bufferWidth and y <= bufferHeight then
|
||||
local index = bufferWidth * (y - 1) + x
|
||||
return newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index]
|
||||
else
|
||||
return 0x000000, 0x000000, " "
|
||||
end
|
||||
end
|
||||
|
||||
local function set(x, y, background, foreground, symbol)
|
||||
if x >= drawLimitX1 and y >= drawLimitY1 and x <= drawLimitX2 and y <= drawLimitY2 then
|
||||
local index = bufferWidth * (y - 1) + x
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] = background, foreground, symbol
|
||||
end
|
||||
end
|
||||
|
||||
local function drawRectangle(x, y, width, height, background, foreground, symbol, transparency)
|
||||
local index, indexStepOnReachOfSquareWidth = bufferWidth * (y - 1) + x, bufferWidth - width
|
||||
for j = y, y + height - 1 do
|
||||
if j >= drawLimitY1 and j <= drawLimitY2 then
|
||||
for i = x, x + width - 1 do
|
||||
if i >= drawLimitX1 and i <= drawLimitX2 then
|
||||
if transparency then
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index] =
|
||||
colorBlend(newFrameBackgrounds[index], background, transparency),
|
||||
colorBlend(newFrameForegrounds[index], background, transparency)
|
||||
else
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
background,
|
||||
foreground,
|
||||
symbol
|
||||
end
|
||||
end
|
||||
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
index = index + indexStepOnReachOfSquareWidth
|
||||
else
|
||||
index = index + bufferWidth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function clear(color, transparency)
|
||||
drawRectangle(1, 1, bufferWidth, bufferHeight, color or 0x0, 0x000000, " ", transparency)
|
||||
end
|
||||
|
||||
local function copy(x, y, width, height)
|
||||
local copyArray, index = {width, height}
|
||||
|
||||
for j = y, y + height - 1 do
|
||||
for i = x, x + width - 1 do
|
||||
if i >= 1 and j >= 1 and i <= bufferWidth and j <= bufferHeight then
|
||||
index = bufferWidth * (j - 1) + i
|
||||
tableInsert(copyArray, newFrameBackgrounds[index])
|
||||
tableInsert(copyArray, newFrameForegrounds[index])
|
||||
tableInsert(copyArray, newFrameSymbols[index])
|
||||
else
|
||||
tableInsert(copyArray, 0x0)
|
||||
tableInsert(copyArray, 0x0)
|
||||
tableInsert(copyArray, " ")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return copyArray
|
||||
end
|
||||
|
||||
local function paste(startX, startY, picture)
|
||||
local imageWidth = picture[1]
|
||||
local bufferIndex, pictureIndex, bufferIndexStepOnReachOfImageWidth =
|
||||
bufferWidth * (startY - 1) + startX,
|
||||
3,
|
||||
bufferWidth - imageWidth
|
||||
|
||||
for y = startY, startY + picture[2] - 1 do
|
||||
if y >= drawLimitY1 and y <= drawLimitY2 then
|
||||
for x = startX, startX + imageWidth - 1 do
|
||||
if x >= drawLimitX1 and x <= drawLimitX2 then
|
||||
newFrameBackgrounds[bufferIndex] = picture[pictureIndex]
|
||||
newFrameForegrounds[bufferIndex] = picture[pictureIndex + 1]
|
||||
newFrameSymbols[bufferIndex] = picture[pictureIndex + 2]
|
||||
end
|
||||
|
||||
bufferIndex, pictureIndex = bufferIndex + 1, pictureIndex + 3
|
||||
end
|
||||
|
||||
bufferIndex = bufferIndex + bufferIndexStepOnReachOfImageWidth
|
||||
else
|
||||
bufferIndex, pictureIndex = bufferIndex + bufferWidth, pictureIndex + imageWidth * 3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function rasterizeLine(x1, y1, x2, y2, method)
|
||||
local inLoopValueFrom,
|
||||
inLoopValueTo,
|
||||
outLoopValueFrom,
|
||||
outLoopValueTo,
|
||||
isReversed,
|
||||
inLoopValueDelta,
|
||||
outLoopValueDelta = x1, x2, y1, y2, false, mathAbs(x2 - x1), mathAbs(y2 - y1)
|
||||
if inLoopValueDelta < outLoopValueDelta then
|
||||
inLoopValueFrom,
|
||||
inLoopValueTo,
|
||||
outLoopValueFrom,
|
||||
outLoopValueTo,
|
||||
isReversed,
|
||||
inLoopValueDelta,
|
||||
outLoopValueDelta = y1, y2, x1, x2, true, outLoopValueDelta, inLoopValueDelta
|
||||
end
|
||||
|
||||
if outLoopValueFrom > outLoopValueTo then
|
||||
outLoopValueFrom, outLoopValueTo = outLoopValueTo, outLoopValueFrom
|
||||
inLoopValueFrom, inLoopValueTo = inLoopValueTo, inLoopValueFrom
|
||||
end
|
||||
|
||||
local outLoopValue, outLoopValueCounter, outLoopValueTriggerIncrement =
|
||||
outLoopValueFrom,
|
||||
1,
|
||||
inLoopValueDelta / outLoopValueDelta
|
||||
local outLoopValueTrigger = outLoopValueTriggerIncrement
|
||||
for inLoopValue = inLoopValueFrom, inLoopValueTo, inLoopValueFrom < inLoopValueTo and 1 or -1 do
|
||||
if isReversed then
|
||||
method(outLoopValue, inLoopValue)
|
||||
else
|
||||
method(inLoopValue, outLoopValue)
|
||||
end
|
||||
|
||||
outLoopValueCounter = outLoopValueCounter + 1
|
||||
if outLoopValueCounter > outLoopValueTrigger then
|
||||
outLoopValue, outLoopValueTrigger = outLoopValue + 1, outLoopValueTrigger + outLoopValueTriggerIncrement
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function rasterizeEllipse(centerX, centerY, radiusX, radiusY, method)
|
||||
local function rasterizeEllipsePoints(XP, YP)
|
||||
method(centerX + XP, centerY + YP)
|
||||
method(centerX - XP, centerY + YP)
|
||||
method(centerX - XP, centerY - YP)
|
||||
method(centerX + XP, centerY - YP)
|
||||
end
|
||||
|
||||
local x, y, changeX, changeY, ellipseError, twoASquare, twoBSquare =
|
||||
radiusX,
|
||||
0,
|
||||
radiusY * radiusY * (1 - 2 * radiusX),
|
||||
radiusX * radiusX,
|
||||
0,
|
||||
2 * radiusX * radiusX,
|
||||
2 * radiusY * radiusY
|
||||
local stoppingX, stoppingY = twoBSquare * radiusX, 0
|
||||
|
||||
while stoppingX >= stoppingY do
|
||||
rasterizeEllipsePoints(x, y)
|
||||
|
||||
y, stoppingY, ellipseError = y + 1, stoppingY + twoASquare, ellipseError + changeY
|
||||
changeY = changeY + twoASquare
|
||||
|
||||
if (2 * ellipseError + changeX) > 0 then
|
||||
x, stoppingX, ellipseError = x - 1, stoppingX - twoBSquare, ellipseError + changeX
|
||||
changeX = changeX + twoBSquare
|
||||
end
|
||||
end
|
||||
|
||||
x, y, changeX, changeY, ellipseError, stoppingX, stoppingY =
|
||||
0,
|
||||
radiusY,
|
||||
radiusY * radiusY,
|
||||
radiusX * radiusX * (1 - 2 * radiusY),
|
||||
0,
|
||||
0,
|
||||
twoASquare * radiusY
|
||||
|
||||
while stoppingX <= stoppingY do
|
||||
rasterizeEllipsePoints(x, y)
|
||||
|
||||
x, stoppingX, ellipseError = x + 1, stoppingX + twoBSquare, ellipseError + changeX
|
||||
changeX = changeX + twoBSquare
|
||||
|
||||
if (2 * ellipseError + changeY) > 0 then
|
||||
y, stoppingY, ellipseError = y - 1, stoppingY - twoASquare, ellipseError + changeY
|
||||
changeY = changeY + twoASquare
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawLine(x1, y1, x2, y2, background, foreground, symbol)
|
||||
rasterizeLine(
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
function(x, y)
|
||||
set(x, y, background, foreground, symbol)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function drawEllipse(centerX, centerY, radiusX, radiusY, background, foreground, symbol)
|
||||
rasterizeEllipse(
|
||||
centerX,
|
||||
centerY,
|
||||
radiusX,
|
||||
radiusY,
|
||||
function(x, y)
|
||||
set(x, y, background, foreground, symbol)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function drawText(x, y, textColor, data, transparency)
|
||||
if y >= drawLimitY1 and y <= drawLimitY2 then
|
||||
local charIndex, bufferIndex = 1, bufferWidth * (y - 1) + x
|
||||
|
||||
for charIndex = 1, unicodeLen(data) do
|
||||
if x >= drawLimitX1 and x <= drawLimitX2 then
|
||||
if transparency then
|
||||
newFrameForegrounds[bufferIndex] =
|
||||
colorBlend(newFrameBackgrounds[bufferIndex], textColor, transparency)
|
||||
else
|
||||
newFrameForegrounds[bufferIndex] = textColor
|
||||
end
|
||||
|
||||
newFrameSymbols[bufferIndex] = unicodeSub(data, charIndex, charIndex)
|
||||
end
|
||||
|
||||
x, bufferIndex = x + 1, bufferIndex + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawImage(startX, startY, picture, blendForeground)
|
||||
local bufferIndex, pictureIndex, imageWidth, backgrounds, foregrounds, alphas, symbols =
|
||||
bufferWidth * (startY - 1) + startX,
|
||||
1,
|
||||
picture[1],
|
||||
picture[3],
|
||||
picture[4],
|
||||
picture[5],
|
||||
picture[6]
|
||||
local bufferIndexStepOnReachOfImageWidth = bufferWidth - imageWidth
|
||||
|
||||
for y = startY, startY + picture[2] - 1 do
|
||||
if y >= drawLimitY1 and y <= drawLimitY2 then
|
||||
for x = startX, startX + imageWidth - 1 do
|
||||
if x >= drawLimitX1 and x <= drawLimitX2 then
|
||||
if alphas[pictureIndex] == 0 then
|
||||
newFrameBackgrounds[bufferIndex], newFrameForegrounds[bufferIndex] =
|
||||
backgrounds[pictureIndex],
|
||||
foregrounds[pictureIndex]
|
||||
elseif alphas[pictureIndex] > 0 and alphas[pictureIndex] < 1 then
|
||||
newFrameBackgrounds[bufferIndex] =
|
||||
colorBlend(
|
||||
newFrameBackgrounds[bufferIndex],
|
||||
backgrounds[pictureIndex],
|
||||
alphas[pictureIndex]
|
||||
)
|
||||
|
||||
if blendForeground then
|
||||
newFrameForegrounds[bufferIndex] =
|
||||
colorBlend(
|
||||
newFrameForegrounds[bufferIndex],
|
||||
foregrounds[pictureIndex],
|
||||
alphas[pictureIndex]
|
||||
)
|
||||
else
|
||||
newFrameForegrounds[bufferIndex] = foregrounds[pictureIndex]
|
||||
end
|
||||
elseif alphas[pictureIndex] == 1 and symbols[pictureIndex] ~= " " then
|
||||
newFrameForegrounds[bufferIndex] = foregrounds[pictureIndex]
|
||||
end
|
||||
|
||||
newFrameSymbols[bufferIndex] = symbols[pictureIndex]
|
||||
end
|
||||
|
||||
bufferIndex, pictureIndex = bufferIndex + 1, pictureIndex + 1
|
||||
end
|
||||
|
||||
bufferIndex = bufferIndex + bufferIndexStepOnReachOfImageWidth
|
||||
else
|
||||
bufferIndex, pictureIndex = bufferIndex + bufferWidth, pictureIndex + imageWidth
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawFrame(x, y, width, height, color)
|
||||
local stringUp, stringDown, x2 =
|
||||
"┌" .. string.rep("─", width - 2) .. "┐",
|
||||
"└" .. string.rep("─", width - 2) .. "┘",
|
||||
x + width - 1
|
||||
|
||||
drawText(x, y, color, stringUp)
|
||||
y = y + 1
|
||||
for i = 1, height - 2 do
|
||||
drawText(x, y, color, "│")
|
||||
drawText(x2, y, color, "│")
|
||||
y = y + 1
|
||||
end
|
||||
drawText(x, y, color, stringDown)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function semiPixelRawSet(index, color, yPercentTwoEqualsZero)
|
||||
local upperPixel, lowerPixel, bothPixel = "▀", "▄", " "
|
||||
local background, foreground, symbol =
|
||||
newFrameBackgrounds[index],
|
||||
newFrameForegrounds[index],
|
||||
newFrameSymbols[index]
|
||||
|
||||
if yPercentTwoEqualsZero then
|
||||
if symbol == upperPixel then
|
||||
if color == foreground then
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
color,
|
||||
foreground,
|
||||
bothPixel
|
||||
else
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
color,
|
||||
foreground,
|
||||
symbol
|
||||
end
|
||||
elseif symbol == bothPixel then
|
||||
if color ~= background then
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
background,
|
||||
color,
|
||||
lowerPixel
|
||||
end
|
||||
else
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
background,
|
||||
color,
|
||||
lowerPixel
|
||||
end
|
||||
else
|
||||
if symbol == lowerPixel then
|
||||
if color == foreground then
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
color,
|
||||
foreground,
|
||||
bothPixel
|
||||
else
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
color,
|
||||
foreground,
|
||||
symbol
|
||||
end
|
||||
elseif symbol == bothPixel then
|
||||
if color ~= background then
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
background,
|
||||
color,
|
||||
upperPixel
|
||||
end
|
||||
else
|
||||
newFrameBackgrounds[index], newFrameForegrounds[index], newFrameSymbols[index] =
|
||||
background,
|
||||
color,
|
||||
upperPixel
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function semiPixelSet(x, y, color)
|
||||
local yFixed = mathCeil(y / 2)
|
||||
if x >= drawLimitX1 and yFixed >= drawLimitY1 and x <= drawLimitX2 and yFixed <= drawLimitY2 then
|
||||
semiPixelRawSet(bufferWidth * (yFixed - 1) + x, color, y % 2 == 0)
|
||||
end
|
||||
end
|
||||
|
||||
local function drawSemiPixelRectangle(x, y, width, height, color)
|
||||
local index, indexStepForward, indexStepBackward, jPercentTwoEqualsZero, jFixed =
|
||||
bufferWidth * (mathCeil(y / 2) - 1) + x,
|
||||
(bufferWidth - width),
|
||||
width
|
||||
for j = y, y + height - 1 do
|
||||
jPercentTwoEqualsZero = j % 2 == 0
|
||||
|
||||
for i = x, x + width - 1 do
|
||||
jFixed = mathCeil(j / 2)
|
||||
semiPixelRawSet(index, color, jPercentTwoEqualsZero)
|
||||
index = index + 1
|
||||
end
|
||||
|
||||
if jPercentTwoEqualsZero then
|
||||
index = index + indexStepForward
|
||||
else
|
||||
index = index - indexStepBackward
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function drawSemiPixelLine(x1, y1, x2, y2, color)
|
||||
rasterizeLine(
|
||||
x1,
|
||||
y1,
|
||||
x2,
|
||||
y2,
|
||||
function(x, y)
|
||||
semiPixelSet(x, y, color)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
local function drawSemiPixelEllipse(centerX, centerY, radiusX, radiusY, color)
|
||||
rasterizeEllipse(
|
||||
centerX,
|
||||
centerY,
|
||||
radiusX,
|
||||
radiusY,
|
||||
function(x, y)
|
||||
semiPixelSet(x, y, color)
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function getPointTimedPosition(firstPoint, secondPoint, time)
|
||||
return {
|
||||
x = firstPoint.x + (secondPoint.x - firstPoint.x) * time,
|
||||
y = firstPoint.y + (secondPoint.y - firstPoint.y) * time
|
||||
}
|
||||
end
|
||||
|
||||
local function getConnectionPoints(points, time)
|
||||
local connectionPoints = {}
|
||||
for point = 1, #points - 1 do
|
||||
tableInsert(connectionPoints, getPointTimedPosition(points[point], points[point + 1], time))
|
||||
end
|
||||
return connectionPoints
|
||||
end
|
||||
|
||||
local function getMainPointPosition(points, time)
|
||||
if #points > 1 then
|
||||
return getMainPointPosition(getConnectionPoints(points, time), time)
|
||||
else
|
||||
return points[1]
|
||||
end
|
||||
end
|
||||
|
||||
local function drawSemiPixelCurve(points, color, precision)
|
||||
local linePoints = {}
|
||||
for time = 0, 1, precision or 0.01 do
|
||||
tableInsert(linePoints, getMainPointPosition(points, time))
|
||||
end
|
||||
|
||||
for point = 1, #linePoints - 1 do
|
||||
drawSemiPixelLine(
|
||||
mathFloor(linePoints[point].x),
|
||||
mathFloor(linePoints[point].y),
|
||||
mathFloor(linePoints[point + 1].x),
|
||||
mathFloor(linePoints[point + 1].y),
|
||||
color
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
local function drawChanges(force)
|
||||
local index, indexStepOnEveryLine, changes =
|
||||
bufferWidth * (drawLimitY1 - 1) + drawLimitX1,
|
||||
(bufferWidth - drawLimitX2 + drawLimitX1 - 1),
|
||||
{}
|
||||
local x, equalChars, equalCharsIndex, charX, charIndex, currentForeground
|
||||
local currentFrameBackground,
|
||||
currentFrameForeground,
|
||||
currentFrameSymbol,
|
||||
changesCurrentFrameBackground,
|
||||
changesCurrentFrameBackgroundCurrentFrameForeground
|
||||
|
||||
local changesCurrentFrameBackgroundCurrentFrameForegroundIndex
|
||||
|
||||
for y = drawLimitY1, drawLimitY2 do
|
||||
x = drawLimitX1
|
||||
while x <= drawLimitX2 do
|
||||
-- Determine if some pixel data was changed (or if <force> argument was passed)
|
||||
if
|
||||
currentFrameBackgrounds[index] ~= newFrameBackgrounds[index] or
|
||||
currentFrameForegrounds[index] ~= newFrameForegrounds[index] or
|
||||
currentFrameSymbols[index] ~= newFrameSymbols[index] or
|
||||
force
|
||||
then
|
||||
-- Make pixel at both frames equal
|
||||
currentFrameBackground, currentFrameForeground, currentFrameSymbol =
|
||||
newFrameBackgrounds[index],
|
||||
newFrameForegrounds[index],
|
||||
newFrameSymbols[index]
|
||||
currentFrameBackgrounds[index] = currentFrameBackground
|
||||
currentFrameForegrounds[index] = currentFrameForeground
|
||||
currentFrameSymbols[index] = currentFrameSymbol
|
||||
|
||||
-- Look for pixels with equal chars from right of current pixel
|
||||
equalChars, equalCharsIndex, charX, charIndex = {currentFrameSymbol}, 2, x + 1, index + 1
|
||||
while charX <= drawLimitX2 do
|
||||
-- Pixels becomes equal only if they have same background and (whitespace char or same foreground)
|
||||
if
|
||||
currentFrameBackground == newFrameBackgrounds[charIndex] and
|
||||
(newFrameSymbols[charIndex] == " " or
|
||||
currentFrameForeground == newFrameForegrounds[charIndex])
|
||||
then
|
||||
-- Make pixel at both frames equal
|
||||
currentFrameBackgrounds[charIndex] = newFrameBackgrounds[charIndex]
|
||||
currentFrameForegrounds[charIndex] = newFrameForegrounds[charIndex]
|
||||
currentFrameSymbols[charIndex] = newFrameSymbols[charIndex]
|
||||
|
||||
equalChars[equalCharsIndex], equalCharsIndex =
|
||||
currentFrameSymbols[charIndex],
|
||||
equalCharsIndex + 1
|
||||
else
|
||||
break
|
||||
end
|
||||
|
||||
charX, charIndex = charX + 1, charIndex + 1
|
||||
end
|
||||
|
||||
-- Group pixels that need to be drawn by background and foreground
|
||||
changes[currentFrameBackground] = changes[currentFrameBackground] or {}
|
||||
changesCurrentFrameBackground = changes[currentFrameBackground]
|
||||
changesCurrentFrameBackground[currentFrameForeground] =
|
||||
changesCurrentFrameBackground[currentFrameForeground] or {index = 1}
|
||||
changesCurrentFrameBackgroundCurrentFrameForeground =
|
||||
changesCurrentFrameBackground[currentFrameForeground]
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex =
|
||||
changesCurrentFrameBackgroundCurrentFrameForeground.index
|
||||
|
||||
changesCurrentFrameBackgroundCurrentFrameForeground[
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex
|
||||
],
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex =
|
||||
x,
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
|
||||
changesCurrentFrameBackgroundCurrentFrameForeground[
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex
|
||||
],
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex =
|
||||
y,
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
|
||||
changesCurrentFrameBackgroundCurrentFrameForeground[
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex
|
||||
],
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex =
|
||||
tableConcat(equalChars),
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex + 1
|
||||
|
||||
x, index, changesCurrentFrameBackgroundCurrentFrameForeground.index =
|
||||
x + equalCharsIndex - 2,
|
||||
index + equalCharsIndex - 2,
|
||||
changesCurrentFrameBackgroundCurrentFrameForegroundIndex
|
||||
end
|
||||
|
||||
x, index = x + 1, index + 1
|
||||
end
|
||||
|
||||
index = index + indexStepOnEveryLine
|
||||
end
|
||||
|
||||
-- Draw grouped pixels on screen
|
||||
for background, foregrounds in pairs(changes) do
|
||||
GPUProxySetBackground(background)
|
||||
|
||||
for foreground, pixels in pairs(foregrounds) do
|
||||
if currentForeground ~= foreground then
|
||||
GPUProxySetForeground(foreground)
|
||||
currentForeground = foreground
|
||||
end
|
||||
|
||||
for i = 1, #pixels, 3 do
|
||||
GPUProxySet(pixels[i], pixels[i + 1], pixels[i + 2])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
changes = nil
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
bindGPU(component.getPrimary("gpu").address)
|
||||
|
||||
return {
|
||||
-- getCoordinates = getCoordinates,
|
||||
getIndex = getIndex,
|
||||
setDrawLimit = setDrawLimit,
|
||||
resetDrawLimit = resetDrawLimit,
|
||||
getDrawLimit = getDrawLimit,
|
||||
flush = flush,
|
||||
setResolution = setResolution,
|
||||
bindScreen = bindScreen,
|
||||
bindGPU = bindGPU,
|
||||
getGPUProxy = getGPUProxy,
|
||||
getResolution = getResolution,
|
||||
getWidth = getWidth,
|
||||
getHeight = getHeight,
|
||||
getCurrentFrameTables = getCurrentFrameTables,
|
||||
getNewFrameTables = getNewFrameTables,
|
||||
rawSet = rawSet,
|
||||
rawGet = rawGet,
|
||||
get = get,
|
||||
set = set,
|
||||
clear = clear,
|
||||
copy = copy,
|
||||
paste = paste,
|
||||
rasterizeLine = rasterizeLine,
|
||||
rasterizeEllipse = rasterizeEllipse,
|
||||
semiPixelRawSet = semiPixelRawSet,
|
||||
semiPixelSet = semiPixelSet,
|
||||
drawChanges = drawChanges,
|
||||
drawRectangle = drawRectangle,
|
||||
drawLine = drawLine,
|
||||
drawEllipse = drawEllipse,
|
||||
drawText = drawText,
|
||||
drawImage = drawImage,
|
||||
drawFrame = drawFrame,
|
||||
drawSemiPixelRectangle = drawSemiPixelRectangle,
|
||||
drawSemiPixelLine = drawSemiPixelLine,
|
||||
drawSemiPixelEllipse = drawSemiPixelEllipse,
|
||||
drawSemiPixelCurve = drawSemiPixelCurve
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
local function render()
|
||||
|
||||
end
|
||||
|
||||
return render
|
7
Programs/monitor-system/api/gui/page/glasses.lua
Normal file
7
Programs/monitor-system/api/gui/page/glasses.lua
Normal file
@ -0,0 +1,7 @@
|
||||
--[[
|
||||
|ove| glasses |
|
||||
|wid| w | w | w |
|
||||
|hel| w | w | w |
|
||||
|sto| w | w | w |
|
||||
|not| power |b|f|
|
||||
--]]
|
54
Programs/monitor-system/api/gui/page/init.lua
Normal file
54
Programs/monitor-system/api/gui/page/init.lua
Normal file
@ -0,0 +1,54 @@
|
||||
-- Import section
|
||||
local doubleBuffer = require("graphics.doubleBuffering")
|
||||
Colors = require("graphics.colors")
|
||||
Unicode = require("unicode")
|
||||
--
|
||||
|
||||
local pages = {
|
||||
overview = require("Overview"),
|
||||
notifications = require("notifications"),
|
||||
stock = require("stock"),
|
||||
help = require("help"),
|
||||
widgets = require("widgets"),
|
||||
glasses = require("glasses")
|
||||
}
|
||||
|
||||
function pages:draw(component, index)
|
||||
if index < 10 then
|
||||
local x = 40 + 40 * ((index - 1) % 3)
|
||||
local y = 10 * math.ceil((index) / 3)
|
||||
doubleBuffer.drawRectangle(x + 1, y + 1, 38, 8, Colors.machineBackground, Colors.machineBackground, "█")
|
||||
doubleBuffer.drawFrame(x + 1, y + 1, 38, 8, Colors.labelColor)
|
||||
doubleBuffer.drawLine(x + 4, y + 4, x + 16, y + 4, Colors.machineBackground, Colors.mainColor, "_")
|
||||
doubleBuffer.drawText(x + 1, y + 1, Colors.labelColor, component.name)
|
||||
doubleBuffer.drawText(
|
||||
x + 4,
|
||||
y + 4,
|
||||
component.working and Colors.workingColor or Colors.errorColor,
|
||||
component.leftInfo
|
||||
)
|
||||
if component.middleInfo then
|
||||
doubleBuffer.drawText(
|
||||
x + 20 - Unicode.len(component.middleInfo),
|
||||
y + 5,
|
||||
Colors.accentB,
|
||||
component.middleInfo
|
||||
)
|
||||
end
|
||||
if component.rightInfo then
|
||||
doubleBuffer.drawText(
|
||||
x + 20 - Unicode.len(component.rightInfo) - 4,
|
||||
y + 5,
|
||||
Colors.accentA,
|
||||
component.rightInfo
|
||||
)
|
||||
end
|
||||
elseif index == 10 then
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
function pages:render()
|
||||
end
|
||||
|
||||
return pages
|
7
Programs/monitor-system/api/gui/page/notifications.lua
Normal file
7
Programs/monitor-system/api/gui/page/notifications.lua
Normal file
@ -0,0 +1,7 @@
|
||||
--[[
|
||||
|gla| notifs. |
|
||||
|wid|ev ti|ev ti|
|
||||
|hel|ev ti|ev ti|
|
||||
|sto|ev ti|ev ti|
|
||||
|ove| power |b|f|
|
||||
--]]
|
7
Programs/monitor-system/api/gui/page/overview.lua
Normal file
7
Programs/monitor-system/api/gui/page/overview.lua
Normal file
@ -0,0 +1,7 @@
|
||||
--[[
|
||||
|gla| overview |
|
||||
|wid| w | w | w |
|
||||
|hel| w | w | w |
|
||||
|sto| w | w | w |
|
||||
|not| power |b|f|
|
||||
--]]
|
7
Programs/monitor-system/api/gui/page/widgets.lua
Normal file
7
Programs/monitor-system/api/gui/page/widgets.lua
Normal file
@ -0,0 +1,7 @@
|
||||
--[[
|
||||
|gla| widgets |
|
||||
|ove| w | w | w |
|
||||
|hel| w | w | w |
|
||||
|sto| w | w | w |
|
||||
|not| power |b|f|
|
||||
--]]
|
@ -3,7 +3,7 @@ local getConsumption = require("domain.energy.get-consumption-usecase")
|
||||
local getProduction = require("domain.energy.get-production-usecase")
|
||||
--
|
||||
|
||||
local function exec(energyProducers, energyBuffer)
|
||||
local function exec(energyBuffer)
|
||||
-- local comsumption = getConsumption(energyBuffer)
|
||||
-- local production = getProduction(energyBuffer)
|
||||
local consumption = energyBuffer:getAverageInput()
|
||||
|
Loading…
x
Reference in New Issue
Block a user