From 4d317509fb7b2a339c16facbddd76283ce6a092a Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Thu, 27 May 2021 21:18:10 -0400 Subject: [PATCH] new GPU is soundly broken. TODO: fix --- include/luares.h | 1 + src/lua/core/textgpu.lua | 164 +++++++++++++-------- src/lua/core/textgpu_old.lua | 271 +++++++++++++++++++++++++++++++++++ 3 files changed, 378 insertions(+), 58 deletions(-) create mode 100644 src/lua/core/textgpu_old.lua diff --git a/include/luares.h b/include/luares.h index 5f3d109..f754bac 100644 --- a/include/luares.h +++ b/include/luares.h @@ -13,6 +13,7 @@ extern char lua_init[]; extern char lua_internet[]; extern char lua_sandbox[]; extern char lua_textgpu[]; +extern char lua_textgpu_old[]; extern char lua_util_buffer[]; extern char lua_util_color[]; extern char lua_util_random[]; diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index cac1045..810a4e6 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -1,37 +1,38 @@ local textgpu = {} -local mapping = { - ["0"] = 0x000000, - ["1"] = 0xFF0000, - ["2"] = 0x00FF00, - ["3"] = 0xFFFF00, - ["4"] = 0x0000FF, - ["5"] = 0xFF00FF, - ["6"] = 0x00FFFF, - ["7"] = 0xFFFFFF, -} - ---[[local nw = io.write -io.write = function(...) - nw(...) - io.flush() - native.sleep(20000) -end]]-- - local write = io.write local flush = io.flush -local background = "0" -local foreground = "0" +local background = 0x000000 -- "0" +local foreground = 0xFFFFFF -- "0" local tbuffer = {} local bbuffer = {} local fbuffer = {} +local palette = { + [0] = 0x0f0f0f, + 0x1e1e1e, + 0x2d2d2d, + 0x3c3c3c, + 0x4b4b4b, + 0x5a5a5a, + 0x696969, + 0x787878, + 0x878787, + 0x969696, + 0xa5a5a5, + 0xb4b4b4, + 0xc3c3c3, + 0xd2d2d2, + 0xe1e1e1, + 0xf0f0f0 +} + local function prepareBuffers(w, h) local tbline = (" "):rep(w) - local bbline = ("0"):rep(w) - local fbline = ("7"):rep(w) + local bbline = ("\0\0\0"):rep(w) -- ("0"):rep(w) + local fbline = ("\255\255\255"):rep(w) -- ("7"):rep(w) for i=1, h do tbuffer[i] = tbline bbuffer[i] = bbline @@ -39,14 +40,28 @@ local function prepareBuffers(w, h) end end +local function setForeground(c) + local r = c & 0xFF0000 + local g = c & 0x00FF00 + local b = c & 0x0000FF + io.write("\27[38;2;", r, ";", g, ";", b, "m") +end + +local function setBackground(c) + local r = c & 0xFF0000 + local g = c & 0x00FF00 + local b = c & 0x0000FF + io.write("\27[48;2;", r, ";", g, ";", b, "m") +end + local usub local function insertString(main, sub, at) checkArg(1, main, "string") checkArg(2, sub, "string") checkArg(3, at, "number") - return usub(main, 1, at - 1) - .. sub .. usub(main, at + (utf8.len(sub) or 0)) + return (usub(main, 1, at - 1) or "") + .. sub .. (usub(main, at + (utf8.len(sub) or 0))) end function textgpu.start() @@ -58,25 +73,33 @@ function textgpu.start() checkArg(1, color, "number") checkArg(2, isPaletteIndex, "boolean", "nil") if isPaletteIndex then - return --TODO: Maybe? + if color > 15 or color < 0 then + error("invalid palette index", 2) + end + return palette[color] end local old = background - background = tostring(math.floor(modules.color.nearest(color, mapping))) - write("\x1b[4" .. background .. "m") + background = color -- tostring(math.floor(modules.color.nearest(color, mapping))) + setBackground(background) + --write("\x1b[4" .. background .. "m") flush() - return mapping[old] + return old -- mapping[old] end function gpu.setForeground(color, isPaletteIndex) checkArg(1, color, "number") checkArg(2, isPaletteIndex, "boolean", "nil") if isPaletteIndex then - return --TODO: Maybe? + if color < 0 or color > 15 then + error("invalid palette index", 2) + end + return palette[color] end local old = foreground - foreground = tostring(math.floor(modules.color.nearest(color, mapping))) - write("\x1b[3" .. foreground .. "m") + foreground = color -- tostring(math.floor(modules.color.nearest(color, mapping))) + setForeground(foreground) + --write("\x1b[3" .. foreground .. "m") flush() - return mapping[old] + return old -- mapping[old] end function gpu.getBackground() return mapping[background], false @@ -84,20 +107,27 @@ function textgpu.start() function gpu.getForeground() return mapping[foreground], false end - function gpu.getPaletteColor() - return nil + function gpu.getPaletteColor(index) + if index < 0 or index > 15 then + error("invalid palette index", 2) + end + return palette[index] end - function gpu.setPaletteColor() - return nil + function gpu.setPaletteColor(index, value) + if index < 0 or index > 15 then + error("invalid palette index", 2) + end + palette[index] = value + return true end function gpu.maxDepth() - return 3 + return 4 end function gpu.setDepth() - return false + return true end function gpu.getDepth() - return 3 + return 4 end function gpu.maxResolution() return termutils.getSize() @@ -122,7 +152,9 @@ function textgpu.start() checkArg(1, x, "number") checkArg(2, y, "number") - return tbuffer[y]:sub(x,x), mapping[fbuffer[y]:sub(x,x)], mapping[bbuffer[y]:sub(x,x)] + return tbuffer[y]:sub(x,x), + fbuffer[y]:sub(x*3-2,x*3):unpack(">I3"), + bbuffer[y]:sub(x*3-2,x*3):unpack(">I3") end function gpu.set(x, y, value, vertical) checkArg(1, x, "number") @@ -137,8 +169,10 @@ function textgpu.start() return false end tbuffer[y] = insertString(tbuffer[y], value, x) - bbuffer[y] = insertString(bbuffer[y], background:rep(utf8.len(value)), x) - fbuffer[y] = insertString(fbuffer[y], foreground:rep(utf8.len(value)), x) + bbuffer[y] = insertString(bbuffer[y], + string.pack(">I3", background):rep(utf8.len(value)), x*3-2) + fbuffer[y] = insertString(fbuffer[y], + string.pack(">I3", foreground):rep(utf8.len(value)), x*3-2) write("\x1b[" .. y .. ";" .. x .. "H" .. value) else --TODO: Buffers! @@ -163,12 +197,14 @@ function textgpu.start() for i=1, h do if i + y - 2 <= _height and i + y > 1 then ttbuf[i] = tbuffer[y + i - 1] and usub(tbuffer[y + i - 1], x, x + w - 1) or (" "):rep(w) - btbuf[i] = bbuffer[y + i - 1] and bbuffer[y + i - 1]:sub(x, x + w - 1) or background:rep(w) - ftbuf[i] = fbuffer[y + i - 1] and fbuffer[y + i - 1]:sub(x, x + w - 1) or foreground:rep(w) + btbuf[i] = bbuffer[y + i - 1] and + bbuffer[y + i - 1]:sub(x*3-2, (x + w - 1)*3) or string.pack(">I3", background):rep(w) + ftbuf[i] = fbuffer[y + i - 1] and + fbuffer[y + i - 1]:sub(x*3-2, (x + w - 1)*3) or string.pack(">I3", foreground):rep(w) else ttbuf[i] = (" "):rep(w) - btbuf[i] = background:rep(w) - ftbuf[i] = foreground:rep(w) + btbuf[i] = string.pack(">I3", background):rep(w) + ftbuf[i] = string.pack(">I3", foreground):rep(w) end end local bg = background @@ -178,10 +214,10 @@ function textgpu.start() local line, linex local lwrite = false for j=1, w do - if btbuf[i]:sub(j,j) ~= bg then + if btbuf[i]:sub(j*3-2,j*3):unpack(">I3") ~= bg then lwrite = true end - if ftbuf[i]:sub(j,j) ~= fg then + if ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") ~= fg then lwrite = true end if not line then linex = j end @@ -190,14 +226,19 @@ function textgpu.start() local wx = (tx + x + linex - 1)|0 local wy = (ty + y + i - 1)|0 if tbuffer[wy] then - write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line) + setBackground(bg) + setForeground(foreground) + --write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m + write("\x1b[" .. wy .. ";" .. wx .. "H" .. line) tbuffer[wy] = insertString(tbuffer[wy], line, wx) - bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx) - fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx) + bbuffer[wy] = insertString(bbuffer[wy], + string.pack(">I3", bg):rep(utf8.len(line)), wx*3-2) + fbuffer[wy] = insertString(fbuffer[wy], + string.pack(">I3", fg):rep(utf8.len(line)), wx*3-2) end - bg = btbuf[i]:sub(j,j) - fg = ftbuf[i]:sub(j,j) + bg = btbuf[i]:sub(j*3-2,j*3):unpack(">I3") + fg = ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") line = nil linex = nil lwrite = false @@ -209,18 +250,25 @@ function textgpu.start() local wx = (tx + x + linex - 1)|0 local wy = (ty + y + i - 1)|0 if tbuffer[wy] then - write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line) + setBackground(bg) + setForeground(fg) + --write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m + write("\x1b[" .. wy .. ";" .. wx .. "H" .. line) tbuffer[wy] = insertString(tbuffer[wy], line, wx) - bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx) - fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx) + bbuffer[wy] = insertString(bbuffer[wy], + string.pack(">I3", bg):rep(utf8.len(line)), wx*3-2) + fbuffer[wy] = insertString(fbuffer[wy], + string.pack(">I3", fg):rep(utf8.len(line)), wx*3-2) end line = nil linex = nil lwrite = false end end - write("\x1b[4" .. background .. "m") - write("\x1b[3" .. foreground .. "m") + setBackground(background) + setForeground(foreground) + --write("\x1b[4" .. background .. "m") + --write("\x1b[3" .. foreground .. "m") flush() return true end diff --git a/src/lua/core/textgpu_old.lua b/src/lua/core/textgpu_old.lua new file mode 100644 index 0000000..cac1045 --- /dev/null +++ b/src/lua/core/textgpu_old.lua @@ -0,0 +1,271 @@ +local textgpu = {} + +local mapping = { + ["0"] = 0x000000, + ["1"] = 0xFF0000, + ["2"] = 0x00FF00, + ["3"] = 0xFFFF00, + ["4"] = 0x0000FF, + ["5"] = 0xFF00FF, + ["6"] = 0x00FFFF, + ["7"] = 0xFFFFFF, +} + +--[[local nw = io.write +io.write = function(...) + nw(...) + io.flush() + native.sleep(20000) +end]]-- + +local write = io.write +local flush = io.flush + +local background = "0" +local foreground = "0" + +local tbuffer = {} +local bbuffer = {} +local fbuffer = {} + +local function prepareBuffers(w, h) + local tbline = (" "):rep(w) + local bbline = ("0"):rep(w) + local fbline = ("7"):rep(w) + for i=1, h do + tbuffer[i] = tbline + bbuffer[i] = bbline + fbuffer[i] = fbline + end +end + +local usub +local function insertString(main, sub, at) + checkArg(1, main, "string") + checkArg(2, sub, "string") + checkArg(3, at, "number") + + return usub(main, 1, at - 1) + .. sub .. usub(main, at + (utf8.len(sub) or 0)) +end + +function textgpu.start() + usub = modules.sandbox.unicode.sub + local _height = 0 + local gpu = {} + function gpu.bind() return false, "This is static bound gpu" end + function gpu.setBackground(color, isPaletteIndex) + checkArg(1, color, "number") + checkArg(2, isPaletteIndex, "boolean", "nil") + if isPaletteIndex then + return --TODO: Maybe? + end + local old = background + background = tostring(math.floor(modules.color.nearest(color, mapping))) + write("\x1b[4" .. background .. "m") + flush() + return mapping[old] + end + function gpu.setForeground(color, isPaletteIndex) + checkArg(1, color, "number") + checkArg(2, isPaletteIndex, "boolean", "nil") + if isPaletteIndex then + return --TODO: Maybe? + end + local old = foreground + foreground = tostring(math.floor(modules.color.nearest(color, mapping))) + write("\x1b[3" .. foreground .. "m") + flush() + return mapping[old] + end + function gpu.getBackground() + return mapping[background], false + end + function gpu.getForeground() + return mapping[foreground], false + end + function gpu.getPaletteColor() + return nil + end + function gpu.setPaletteColor() + return nil + end + function gpu.maxDepth() + return 3 + end + function gpu.setDepth() + return false + end + function gpu.getDepth() + return 3 + end + function gpu.maxResolution() + return termutils.getSize() + end + function gpu.getResolution() + return termutils.getSize() + end + function gpu.getViewport() + return termutils.getSize() + end + function gpu.setViewport(w, h) + checkArg(1, w, "number") + checkArg(2, h, "number") + return false, "Viewport not supported for this gpu" + end + function gpu.setResolution(w, h) + checkArg(1, w, "number") + checkArg(2, h, "number") + return false, "Non resizeable gpu" + end + function gpu.get(x, y) + checkArg(1, x, "number") + checkArg(2, y, "number") + + return tbuffer[y]:sub(x,x), mapping[fbuffer[y]:sub(x,x)], mapping[bbuffer[y]:sub(x,x)] + end + function gpu.set(x, y, value, vertical) + checkArg(1, x, "number") + checkArg(2, y, "number") + checkArg(3, value, "string") + checkArg(4, vertical, "boolean", "nil") + x = math.floor(x) + y = math.floor(y) + if not vertical then + if not tbuffer[y] then + native.log("GPU Set failed: under buffer") + return false + end + tbuffer[y] = insertString(tbuffer[y], value, x) + bbuffer[y] = insertString(bbuffer[y], background:rep(utf8.len(value)), x) + fbuffer[y] = insertString(fbuffer[y], foreground:rep(utf8.len(value)), x) + write("\x1b[" .. y .. ";" .. x .. "H" .. value) + else + --TODO: Buffers! + write("\x1b[" .. y .. ";" .. x .. "H") + value:gsub("([%z\1-\127\194-\244][\128-\191]*)", function(c) + write(c .. "\x1b[D\x1b[B") + end) + end + flush() + return true + end + function gpu.copy(x, y, w, h, tx, ty) --TODO: Check(check X multiple times) + checkArg(1, x, "number") + checkArg(2, y, "number") + checkArg(3, w, "number") + checkArg(4, h, "number") + checkArg(5, tx, "number") + checkArg(6, ty, "number") + local ttbuf = {} + local btbuf = {} + local ftbuf = {} + for i=1, h do + if i + y - 2 <= _height and i + y > 1 then + ttbuf[i] = tbuffer[y + i - 1] and usub(tbuffer[y + i - 1], x, x + w - 1) or (" "):rep(w) + btbuf[i] = bbuffer[y + i - 1] and bbuffer[y + i - 1]:sub(x, x + w - 1) or background:rep(w) + ftbuf[i] = fbuffer[y + i - 1] and fbuffer[y + i - 1]:sub(x, x + w - 1) or foreground:rep(w) + else + ttbuf[i] = (" "):rep(w) + btbuf[i] = background:rep(w) + ftbuf[i] = foreground:rep(w) + end + end + local bg = background + local fg = foreground + + for i=1, h do + local line, linex + local lwrite = false + for j=1, w do + if btbuf[i]:sub(j,j) ~= bg then + lwrite = true + end + if ftbuf[i]:sub(j,j) ~= fg then + lwrite = true + end + if not line then linex = j end + line = (line or "") + if lwrite then + local wx = (tx + x + linex - 1)|0 + local wy = (ty + y + i - 1)|0 + if tbuffer[wy] then + write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line) + tbuffer[wy] = insertString(tbuffer[wy], line, wx) + bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx) + fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx) + end + + bg = btbuf[i]:sub(j,j) + fg = ftbuf[i]:sub(j,j) + line = nil + linex = nil + lwrite = false + end + if not line then linex = j end + line = (line or "") .. usub(ttbuf[i], j,j) + end + if line then + local wx = (tx + x + linex - 1)|0 + local wy = (ty + y + i - 1)|0 + if tbuffer[wy] then + write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m\x1b[" .. wy .. ";" .. wx .. "H" .. line) + tbuffer[wy] = insertString(tbuffer[wy], line, wx) + bbuffer[wy] = insertString(bbuffer[wy], bg:rep(utf8.len(line)), wx) + fbuffer[wy] = insertString(fbuffer[wy], fg:rep(utf8.len(line)), wx) + end + line = nil + linex = nil + lwrite = false + end + end + write("\x1b[4" .. background .. "m") + write("\x1b[3" .. foreground .. "m") + flush() + return true + end + function gpu.fill(x, y, w, h, ch) + checkArg(1, x, "number") + checkArg(2, y, "number") + checkArg(3, w, "number") + checkArg(4, h, "number") + checkArg(5, ch, "string") + ch = usub(ch, 1, 1):rep(math.floor(w)) + for i=1, h do + if i + y - 1 <= _height and i + y > 1 then + gpu.set(x, y + i - 1, ch) + end + end + return true + end + + local screenAddr + + function gpu.getScreen() + return screenAddr + end + + if not termutils.init() then + return nil, "Cannot initialize terminal based gpu" + end + write("\x1b[?25l") --Disable cursor + local w, h = gpu.getResolution() + _height = h + prepareBuffers(w, h) + gpu.setForeground(0xFFFFFF) + gpu.setBackground(0x000000) + + local gpuaddr = modules.component.api.register(nil, "gpu", gpu) + screenAddr = modules.component.api.register(nil, "screen", {getKeyboards = function() return {"TODO:SetThisUuid"} end}) --verry dummy screen, TODO: make it better, kbd uuid also in epoll.c + modules.component.api.register("TODO:SetThisUuid", "keyboard", {}) + + deadhooks[#deadhooks + 1] = function() + write("\x1b[?25h\x1b[" .. ((h-1)|0) .. ";1H") --Enable cursor on quit + io.flush() + termutils.restore() + end + + return gpuaddr +end + +return textgpu