controlpanel/lua/framebuffer.tl

139 lines
3.7 KiB
Plaintext

local record ScreenContent
x: integer
y: integer
width: integer
height: integer
blink: boolean
fg: integer
text: {string}
fg_color: {string}
bg_color: {string}
palette: {integer}
end
local record Buffer
target: term.Redirect
serialize: function(): ScreenContent
is_dirty: function(): boolean
clear_dirty: function()
end
local COLOR_LOOKUP <const> : {number: integer} = {
[colors.white] = 0x0,
[colors.orange] = 0x1,
[colors.magenta] = 0x2,
[colors.lightBlue] = 0x3,
[colors.yellow] = 0x4,
[colors.lime] = 0x5,
[colors.pink] = 0x6,
[colors.gray] = 0x7,
[colors.lightGray] = 0x8,
[colors.cyan] = 0x9,
[colors.purple] = 0xA,
[colors.blue] = 0xB,
[colors.brown] = 0xC,
[colors.green] = 0xD,
[colors.red] = 0xE,
[colors.black] = 0xF,
}
local function wrap(parent: term.Redirect): Buffer
local x, y = parent.getCursorPos()
local width, height = parent.getSize()
local blink = parent.getCursorBlink()
local fg = COLOR_LOOKUP[parent.getTextColor()]
local palette: {number} = {}
for c = 0, 15 do
palette[c+1] = colors.packRGB(parent.getPaletteColor(2^c))
end
local dirty: boolean = false
local win = window.create(parent, 1, 1, width, height)
local overrides: table = {}
overrides.setCursorPos = function(new_x: integer, new_y: integer)
win.setCursorPos(new_x, new_y)
x = new_x
y = new_y
end
overrides.setCursorBlink = function(new_blink: boolean)
win.setCursorBlink(new_blink)
blink = new_blink
end
overrides.setTextColor = function(new_color: number)
local r = { pcall(win.setTextColor, new_color) }
if not r[1] then
error((r[2] as string):sub(8))
end
fg = COLOR_LOOKUP[new_color]
end
overrides.setTextColour = overrides.setTextColor
overrides.setPaletteColor = function(color: number, r_rgb: number, g: number | nil, b: number | nil)
local r = { pcall(win.setPaletteColor, color, r_rgb, g, b) }
if not r[1] then
error((r[2] as string):sub(8))
end
local index = COLOR_LOOKUP[color]
if g == nil then
palette[1 + index] = r_rgb
else
palette[1 + index] = colors.packRGB(r_rgb, g, b)
end
end
overrides.setPaletteColour = overrides.setPaletteColor
local target = setmetatable(overrides, {
__index = function(_: table, k: any): any
dirty = true
return (win as table)[k]
end
}) as term.Redirect
target.setTextColor(colors.white)
target.setBackgroundColor(colors.black)
target.setCursorPos(1,1)
target.clear()
local buffer: Buffer = {
target = target
}
buffer.serialize = function(): ScreenContent
local text: {string} = {}
local fg_color: {string} = {}
local bg_color: {string} = {}
for i = 1, height do
local t, f, b = win.getLine(i)
table.insert(text, t)
table.insert(fg_color, f)
table.insert(bg_color, b)
end
return {
x = x,
y = y,
width = width,
height = height,
blink = blink,
fg = fg,
text = text,
fg_color = fg_color,
bg_color = bg_color,
palette = palette
}
end
buffer.is_dirty = function(): boolean
return dirty
end
buffer.clear_dirty = function() dirty = false end
return buffer
end
return { wrap = wrap, Buffer = Buffer, ScreenContent = ScreenContent }