mirror of
https://github.com/NeoFlock/neonucleus.git
synced 2025-09-25 01:23:31 +02:00
130 lines
3.3 KiB
Lua
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
|