ldd-CC/lddwindow.lua

300 lines
8.1 KiB
Lua

local doGlobalize = false
local lddwindow = {}
local to_colors = {
[" "] = 0,
["0"] = colors.white,
["1"] = colors.orange,
["2"] = colors.magenta,
["3"] = colors.lightBlue,
["4"] = colors.yellow,
["5"] = colors.lime,
["6"] = colors.pink,
["7"] = colors.gray,
["8"] = colors.lightGray,
["9"] = colors.cyan,
["a"] = colors.purple,
["b"] = colors.blue,
["c"] = colors.brown,
["d"] = colors.green,
["e"] = colors.red,
["f"] = colors.black,
}
local to_blit = {}
for k,v in pairs(to_colors) do
to_blit[v] = k
end
local stringSub = string.sub
local stringGsub = string.gsub
local tableConcat = table.concat
lddwindow.newWindow = function(nativeTerm, x, y, width, height, visible)
local output = {
info = {
buffer = {{},{},{}},
x = x,
y = y,
textColor = "0",
backColor = "f",
cursorX = 1,
cursorY = 1,
nativeTerm = nativeTerm or term.current(),
width = width,
height = height,
blink = true,
palette = {},
}
}
if visible == nil then
output.info.visible = true
elseif type(visible) == "boolean" then
output.info.visible = visible
else
output.info.visible = true
end
local genTblLine = function(char, length)
local blankLine = {}
for i = 1, length do
blankLine[i] = char
end
return blankLine
end
for i = 0, 15 do
-- output.info.palette[2^i] = output.info.nativeTerm.nativePaletteColor(2^i)
output.info.palette[2^i] = term.nativePaletteColor(2^i)
end
local fixBuffer = function()
for y = math.max(output.info.height, #output.info.buffer[1]), 1, -1 do
if y > output.info.height then
output.info.buffer[1][y] = nil
output.info.buffer[2][y] = nil
output.info.buffer[3][y] = nil
else
output.info.buffer[1][y] = output.info.buffer[1][y] or {}
output.info.buffer[2][y] = output.info.buffer[2][y] or {}
output.info.buffer[3][y] = output.info.buffer[3][y] or {}
for x = math.max(output.info.width, #(output.info.buffer[1][1] or {})), 1, -1 do
if x > output.info.width then
output.info.buffer[1][y][x] = nil
output.info.buffer[2][y][x] = nil
output.info.buffer[3][y][x] = nil
else
output.info.buffer[1][y][x] = output.info.buffer[1][y][x] or " "
output.info.buffer[2][y][x] = output.info.buffer[2][y][x] or output.info.textColor
output.info.buffer[3][y][x] = output.info.buffer[3][y][x] or output.info.backColor
end
end
end
end
end
fixBuffer()
output.reposition = function(x, y, width, height)
output.info.x = tonumber(x) or output.info.x
output.info.y = tonumber(y) or output.info.y
output.info.width = tonumber(width) or output.info.width
output.info.height = tonumber(height) or output.info.height
fixBuffer()
end
output.setCursorPos = function(x, y)
output.info.cursorX = x or output.info.cursorX
output.info.cursorY = y or output.info.cursorY
end
output.getCursorPos = function()
return output.info.cursorX, output.info.cursorY
end
output.setCursorBlink = function(blink)
output.info.blink = blink and true or false
end
output.getCursorBlink = function(blink)
return output.info.blink
end
output.isColor = function()
return true
end
output.isColour = output.isColor
output.getSize = function()
return output.info.width, output.info.height
end
output.current = function()
return output
end
output.clear = function()
for y = 1, output.info.height do
output.info.buffer[1][y] = genTblLine(" ", output.info.width)
output.info.buffer[2][y] = genTblLine(output.info.textColor, output.info.width)
output.info.buffer[3][y] = genTblLine(output.info.backColor, output.info.width)
end
end
output.clearLine = function()
if output.info.cursorY >= 1 and output.info.cursorY <= output.info.height then
output.info.buffer[1][output.info.cursorY] = genTblLine(" ", output.info.width)
output.info.buffer[2][output.info.cursorY] = genTblLine(output.info.textColor, output.info.width)
output.info.buffer[3][output.info.cursorY] = genTblLine(output.info.backColor, output.info.width)
end
end
output.setTextColor = function(color)
output.info.textColor = to_blit[color]
end
output.setTextColour = output.setTextColor
output.setBackgroundColor = function(color)
output.info.backColor = to_blit[color]
end
output.setBackgroundColour = output.setBackgroundColor
output.getTextColor = function()
return output.info.textColor
end
output.getTextColour = output.getTextColor
output.getBackgroundColor = function()
return output.info.backColor
end
output.getBackgroundColour = output.getBackgroundColor
output.write = function(char)
local cx
if output.info.cursorY >= 1 and output.info.cursorY <= height then
for i = 1, #char do
cx = -1 + i + output.info.cursorX
if cx >= 1 and cx <= output.info.width then
output.info.buffer[1][output.info.cursorY][cx] = stringSub(char, i, i)
output.info.buffer[2][output.info.cursorY][cx] = output.info.textColor
output.info.buffer[3][output.info.cursorY][cx] = output.info.backColor
end
end
end
output.info.cursorX = output.info.cursorX + #char
end
output.blit = function(char, text, back)
local cx
assert(#char == #text and #text == #back, "arguments must be same length")
if output.info.cursorY >= 1 and output.info.cursorY <= height then
for i = 1, #char do
cx = -1 + i + output.info.cursorX
if cx >= 1 and cx <= output.info.width then
output.info.buffer[1][output.info.cursorY][cx] = stringSub(char, i, i)
output.info.buffer[2][output.info.cursorY][cx] = stringSub(text, i, i)
output.info.buffer[3][output.info.cursorY][cx] = stringSub(back, i, i)
end
end
end
output.info.cursorX = output.info.cursorX + #char
end
output.native = function()
if true then
return output.info.nativeTerm
else
return output
end
end
output.nativePaletteColor = output.info.nativeTerm.nativePaletteColor
output.nativePaletteColour = output.info.nativeTerm.nativePaletteColour
output.setPaletteColor = function(slot, r, g, b)
output.info.palette[slot] = {r, g, b}
end
output.setPaletteColour = output.setPaletteColor
output.getPaletteColor = function(slot)
return output.info.palette[slot][1], output.info.palette[slot][2], output.info.palette[slot][3]
end
output.getPaletteColour = output.getPaletteColor
output.scroll = function(distance)
for y = distance, output.info.height do
for c = 1, 3 do
output.info.buffer[c][y] = output.info.buffer[c][y + distance] or genTblLine(" ", output.info.width)
end
end
end
output.setVisible = function(visible)
output.info.visible = visible and true or false
end
-- draws the window
output.render = function(x, y, ...)
x = x or output.info.x
y = y or output.info.y
-- can render to multiple terminals
local termList = {...}
if output.info.visible then
if #termList == 0 then
nTerm = nTerm or output.info.nativeTerm
for yy = 1, output.info.height do
nTerm.setCursorPos(x, -1 + y + yy)
nTerm.blit(
tableConcat(output.info.buffer[1][yy]),
tableConcat(output.info.buffer[2][yy]),
tableConcat(output.info.buffer[3][yy])
)
end
else
for i = 1, #termList do
for yy = 1, output.info.height do
termList[i].setCursorPos(x, -1 + y + yy)
termList[i].blit(
tableConcat(output.info.buffer[1][yy]),
tableConcat(output.info.buffer[2][yy]),
tableConcat(output.info.buffer[3][yy])
)
end
end
end
end
end
-- turns window into an NFT string image
output.screenshot = function()
local image = ""
local tcol, bcol
local tchar, bchar = string.char(31), string.char(30)
for y = 1, output.info.height do
tcol, bcol = "", ""
for x = 1, output.info.width do
if tcol ~= output.info.buffer[2][y][x] then
tcol = output.info.buffer[2][y][x]
image = image .. tchar .. tcol
end
if bcol ~= output.info.buffer[3][y][x] then
bcol = output.info.buffer[3][y][x]
image = image .. bchar .. bcol
end
image = image .. output.info.buffer[1][y][x]
end
if y < output.info.height then
image = image .. "\n"
end
end
return image
end
return output
end
if doGlobalize then
_G.lddwindow = lddwindow
end
return lddwindow