IonutParau 687cfebd00 testing version of LuaBIOS and OpenOS
people were having issues getting them to work so now we promote consistency
2025-06-28 20:41:49 +02:00

130 lines
3.3 KiB
Lua

local text = require("text")
local rules = {}
local vt100 = {rules=rules}
local full
-- colors, blinking, and reverse
-- [%d+;%d+;..%d+m
-- cost: 2,250
rules[{"%[", "[%d;]*", "m"}] = function(window, _, number_text)
-- prefix and suffix ; act as reset
-- e.g. \27[41;m is actually 41 followed by a reset
local colors = {0x0,0xff0000,0x00ff00,0xffff00,0x0000ff,0xff00ff,0x00B6ff,0xffffff}
local fg, bg = window.gpu.setForeground, window.gpu.setBackground
if window.flip then
fg, bg = bg, fg
end
number_text = " _ " .. number_text:gsub("^;$", ""):gsub(";", " _ ") .. " _ "
local parts = text.internal.tokenize(number_text)
local last_was_break
for _,part in ipairs(parts) do
local num = tonumber(part[1].txt)
last_was_break, num = not num, num or last_was_break and 0
local flip = num == 7
if flip then
if not window.flip then
local rgb, pal = bg(window.gpu.getForeground())
fg(pal or rgb, not not pal)
fg, bg = bg, fg
end
elseif num == 5 then
window.blink = true
elseif num == 0 then
bg(colors[1])
fg(colors[8])
elseif num then
num = num - 29
local set = fg
if num > 10 then
num = num - 10
set = bg
end
local color = colors[num]
if color then
set(color)
end
end
window.flip = flip
end
end
local function save_attributes(window, seven, s)
if seven == "7" or s == "s" then
window.saved =
{
window.x,
window.y,
{window.gpu.getBackground()},
{window.gpu.getForeground()},
window.flip,
window.blink
}
else
local data = window.saved or {1, 1, {0x0}, {0xffffff}, window.flip, window.blink}
window.x = data[1]
window.y = data[2]
window.gpu.setBackground(table.unpack(data[3]))
window.gpu.setForeground(table.unpack(data[4]))
window.flip = data[5]
window.blink = data[6]
end
end
-- 7 save cursor position and attributes
-- 8 restore cursor position and attributes
rules[{"[78]"}] = save_attributes
-- s save cursor position
-- u restore cursor position
rules[{"%[", "[su]"}] = save_attributes
-- returns: anything that failed to parse
function vt100.parse(window)
if window.output_buffer:sub(1, 1) ~= "\27" then
return ""
end
local any_valid
for rule,action in pairs(rules) do
local last_index = 1 -- start at 1 to skip the \27
local captures = {}
for _,pattern in ipairs(rule) do
if last_index >= #window.output_buffer then
any_valid = true
break
end
local si, ei, capture = window.output_buffer:find("^(" .. pattern .. ")", last_index + 1)
if not si then
break
end
captures[#captures + 1] = capture
last_index = ei
end
if #captures == #rule then
action(window, table.unpack(captures))
window.output_buffer = window.output_buffer:sub(last_index + 1)
return ""
end
end
if not full then
-- maybe it did satisfy a rule, load more rules
full = true
dofile("/lib/core/full_vt.lua")
return vt100.parse(window)
end
if not any_valid then
-- malformed
window.output_buffer = window.output_buffer:sub(2)
return "\27"
end
-- else, still consuming
end
return vt100