From 9cb94c6a6c35e7556738898597c90ac1da5b7d66 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Thu, 27 May 2021 19:20:59 -0400 Subject: [PATCH 01/17] add i686 support --- .gitignore | 1 + scripts/dependencies.sh | 6 +++++- src/lua/core/component.lua | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6883938..a1af92b 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ /usereeprom.lua /run /root* +/musl-cross-make diff --git a/scripts/dependencies.sh b/scripts/dependencies.sh index 3689d3d..afd4e5e 100755 --- a/scripts/dependencies.sh +++ b/scripts/dependencies.sh @@ -42,6 +42,10 @@ case "$1" in TOOL=powerpc-linux-musl OUT=$TOOL ;; + i686 ) + TOOL=i686-linux-musl + OUT=i686-linux-musl + ;; *) echo "Invalid target!" ; exit 1 ;; esac @@ -60,7 +64,7 @@ cd dependencies if [ $2 = "libressl" ] || [ $# -lt 2 ]; then - git clone https://github.com/libressl-portable/portable.git libressl + git clone --depth 1 https://github.com/libressl-portable/portable.git libressl cd libressl ./autogen.sh CFLAGS="-fdata-sections -ffunction-sections" ./configure --host=$TOOL diff --git a/src/lua/core/component.lua b/src/lua/core/component.lua index e409479..655f7be 100644 --- a/src/lua/core/component.lua +++ b/src/lua/core/component.lua @@ -50,7 +50,7 @@ function api.register(address, ctype, proxy, doc) end components[address] = {address = address, type = ctype, doc = doc or {}} components[address].rawproxy = proxy - components[address].proxy = {} + components[address].proxy = {address = address, type = ctype, slot = -1} for k,v in pairs(proxy) do if type(v) == "function" then components[address].proxy[k] = setmetatable({name=k,address=address}, componentCallback) -- 2.30.2 From 6de77feaae0ca4555147f2adcfb1a78c71845194 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Thu, 27 May 2021 19:27:49 -0400 Subject: [PATCH 02/17] hopefully fix kernel panics making BSODs not visible under some circumstances? --- src/lua/core/boot.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lua/core/boot.lua b/src/lua/core/boot.lua index 37175d6..c21744b 100644 --- a/src/lua/core/boot.lua +++ b/src/lua/core/boot.lua @@ -31,7 +31,11 @@ function boot.boot() gpu.setBackground(0x000000) native.sleep(4000000) - os.exit(1) + if modules.computer and modules.computer.shutdown() then + modules.computer.shutdown() + else + os.exit(1) + end end) end -- 2.30.2 From 4052720c2ce65f31875ce24954fd4c3faa06d2f2 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Thu, 27 May 2021 19:47:55 -0400 Subject: [PATCH 03/17] BSODs now busywait rather than kernel panicking. this makes it so that errors are not obscured. --- src/lua/core/boot.lua | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lua/core/boot.lua b/src/lua/core/boot.lua index c21744b..4addf22 100644 --- a/src/lua/core/boot.lua +++ b/src/lua/core/boot.lua @@ -31,11 +31,7 @@ function boot.boot() gpu.setBackground(0x000000) native.sleep(4000000) - if modules.computer and modules.computer.shutdown() then - modules.computer.shutdown() - else - os.exit(1) - end + while true do --[[NOTHING]] end end) end -- 2.30.2 From 4d317509fb7b2a339c16facbddd76283ce6a092a Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Thu, 27 May 2021 21:18:10 -0400 Subject: [PATCH 04/17] 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 -- 2.30.2 From 7367dd1d597d34306d593019907dc3b2b8a2a077 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Thu, 27 May 2021 21:30:42 -0400 Subject: [PATCH 05/17] textgpu: still mildly broken, but not crash-the-whole-fuckin-thing broken --- include/luares.h | 1 + src/lua/core/textgpu.lua | 169 +++++++------------ src/lua/core/textgpu_new.lua | 319 +++++++++++++++++++++++++++++++++++ 3 files changed, 383 insertions(+), 106 deletions(-) create mode 100644 src/lua/core/textgpu_new.lua diff --git a/include/luares.h b/include/luares.h index f754bac..33b8601 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_new[]; extern char lua_textgpu_old[]; extern char lua_util_buffer[]; extern char lua_util_color[]; diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index 810a4e6..f33870b 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -1,38 +1,40 @@ local textgpu = {} +local mapping = {} + +-- generate the mapping + +local i = 0 +for g=0, 255, 0x24 do + for b=0, 255, 0x40 do + for r=0, 255, 0x33 do + mapping[tostring(i)] = (r * 0x10000) + (g * 0x100) + b + i = i + 1 + end + end +end + +--[[local nw = io.write +io.write = function(...) + nw(...) + io.flush() + native.sleep(20000) +end]]-- + local write = io.write local flush = io.flush -local background = 0x000000 -- "0" -local foreground = 0xFFFFFF -- "0" +local background = "\0" +local foreground = "\255" 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\0\0"):rep(w) -- ("0"):rep(w) - local fbline = ("\255\255\255"):rep(w) -- ("7"):rep(w) + local bbline = ("\0"):rep(w) + local fbline = ("\7"):rep(w) for i=1, h do tbuffer[i] = tbline bbuffer[i] = bbline @@ -40,28 +42,14 @@ 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) or "") - .. sub .. (usub(main, at + (utf8.len(sub) or 0))) + return usub(main, 1, at - 1) + .. sub .. usub(main, at + (utf8.len(sub) or 0)) end function textgpu.start() @@ -73,33 +61,25 @@ function textgpu.start() checkArg(1, color, "number") checkArg(2, isPaletteIndex, "boolean", "nil") if isPaletteIndex then - if color > 15 or color < 0 then - error("invalid palette index", 2) - end - return palette[color] + return --TODO: Maybe? end local old = background - background = color -- tostring(math.floor(modules.color.nearest(color, mapping))) - setBackground(background) - --write("\x1b[4" .. background .. "m") + background = tostring(math.floor(modules.color.nearest(color, mapping))) + write("\x1b[48;5;" .. background:byte() .. "m") flush() - return old -- mapping[old] + return mapping[old] end function gpu.setForeground(color, isPaletteIndex) checkArg(1, color, "number") checkArg(2, isPaletteIndex, "boolean", "nil") if isPaletteIndex then - if color < 0 or color > 15 then - error("invalid palette index", 2) - end - return palette[color] + return --TODO: Maybe? end local old = foreground - foreground = color -- tostring(math.floor(modules.color.nearest(color, mapping))) - setForeground(foreground) - --write("\x1b[3" .. foreground .. "m") + foreground = tostring(math.floor(modules.color.nearest(color, mapping))) + write("\x1b[38;5;" .. foreground:byte() .. "m") flush() - return old -- mapping[old] + return mapping[old] end function gpu.getBackground() return mapping[background], false @@ -107,27 +87,20 @@ function textgpu.start() function gpu.getForeground() return mapping[foreground], false end - function gpu.getPaletteColor(index) - if index < 0 or index > 15 then - error("invalid palette index", 2) - end - return palette[index] + function gpu.getPaletteColor() + return nil end - function gpu.setPaletteColor(index, value) - if index < 0 or index > 15 then - error("invalid palette index", 2) - end - palette[index] = value - return true + function gpu.setPaletteColor() + return nil end function gpu.maxDepth() - return 4 + return 3 end function gpu.setDepth() - return true + return false end function gpu.getDepth() - return 4 + return 3 end function gpu.maxResolution() return termutils.getSize() @@ -152,9 +125,7 @@ function textgpu.start() checkArg(1, x, "number") checkArg(2, y, "number") - 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") + 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") @@ -169,10 +140,8 @@ function textgpu.start() return false end tbuffer[y] = insertString(tbuffer[y], 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) + 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! @@ -197,14 +166,12 @@ 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*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) + 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] = string.pack(">I3", background):rep(w) - ftbuf[i] = string.pack(">I3", foreground):rep(w) + btbuf[i] = background:rep(w) + ftbuf[i] = foreground:rep(w) end end local bg = background @@ -214,10 +181,10 @@ function textgpu.start() local line, linex local lwrite = false for j=1, w do - if btbuf[i]:sub(j*3-2,j*3):unpack(">I3") ~= bg then + if btbuf[i]:sub(j,j) ~= bg then lwrite = true end - if ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") ~= fg then + if ftbuf[i]:sub(j,j) ~= fg then lwrite = true end if not line then linex = j end @@ -226,19 +193,15 @@ function textgpu.start() local wx = (tx + x + linex - 1)|0 local wy = (ty + y + i - 1)|0 if tbuffer[wy] then - setBackground(bg) - setForeground(foreground) - --write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m - write("\x1b[" .. wy .. ";" .. wx .. "H" .. line) + write("\x1b[48;5;" .. bg:byte() .. "m\x1b[38;5;" .. fg:byte() .. "m\x1b[" .. wy + .. ";" .. wx .. "H" .. line) tbuffer[wy] = insertString(tbuffer[wy], 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) + 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*3-2,j*3):unpack(">I3") - fg = ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") + bg = btbuf[i]:sub(j,j) + fg = ftbuf[i]:sub(j,j) line = nil linex = nil lwrite = false @@ -250,25 +213,19 @@ function textgpu.start() local wx = (tx + x + linex - 1)|0 local wy = (ty + y + i - 1)|0 if tbuffer[wy] then - setBackground(bg) - setForeground(fg) - --write("\x1b[4" .. bg .. "m\x1b[3" .. fg .. "m - write("\x1b[" .. wy .. ";" .. wx .. "H" .. line) + write("\x1b[48;5;" .. bg:byte() .. "m\x1b[38;5;" .. fg:byte() .. "m\x1b[" .. wy + .. ";" .. wx .. "H" .. line) tbuffer[wy] = insertString(tbuffer[wy], 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) + 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 - setBackground(background) - setForeground(foreground) - --write("\x1b[4" .. background .. "m") - --write("\x1b[3" .. foreground .. "m") + write("\x1b[48;5;" .. background:byte() .. "m") + write("\x1b[38;5;" .. foreground:byte() .. "m") flush() return true end diff --git a/src/lua/core/textgpu_new.lua b/src/lua/core/textgpu_new.lua new file mode 100644 index 0000000..810a4e6 --- /dev/null +++ b/src/lua/core/textgpu_new.lua @@ -0,0 +1,319 @@ +local textgpu = {} + +local write = io.write +local flush = io.flush + +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\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 + fbuffer[i] = fbline + 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) or "") + .. 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 + if color > 15 or color < 0 then + error("invalid palette index", 2) + end + return palette[color] + end + local old = background + background = color -- tostring(math.floor(modules.color.nearest(color, mapping))) + setBackground(background) + --write("\x1b[4" .. background .. "m") + flush() + return old -- mapping[old] + end + function gpu.setForeground(color, isPaletteIndex) + checkArg(1, color, "number") + checkArg(2, isPaletteIndex, "boolean", "nil") + if isPaletteIndex then + if color < 0 or color > 15 then + error("invalid palette index", 2) + end + return palette[color] + end + local old = foreground + foreground = color -- tostring(math.floor(modules.color.nearest(color, mapping))) + setForeground(foreground) + --write("\x1b[3" .. foreground .. "m") + flush() + return old -- mapping[old] + end + function gpu.getBackground() + return mapping[background], false + end + function gpu.getForeground() + return mapping[foreground], false + end + function gpu.getPaletteColor(index) + if index < 0 or index > 15 then + error("invalid palette index", 2) + end + return palette[index] + end + 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 4 + end + function gpu.setDepth() + return true + end + function gpu.getDepth() + return 4 + 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), + 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") + 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], + 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! + 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*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] = string.pack(">I3", background):rep(w) + ftbuf[i] = string.pack(">I3", 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*3-2,j*3):unpack(">I3") ~= bg then + lwrite = true + end + if ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") ~= 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 + 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], + 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*3-2,j*3):unpack(">I3") + fg = ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") + 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 + 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], + 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 + setBackground(background) + setForeground(foreground) + --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 -- 2.30.2 From b9747364d7187632af82443273da187a241c713e Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 28 May 2021 00:14:36 -0400 Subject: [PATCH 06/17] completely rewrote gpu, still broken but getting better, i hope? --- include/luares.h | 1 - src/lua/core/textgpu.lua | 401 ++++++++++++++++++----------------- src/lua/core/textgpu_new.lua | 319 ---------------------------- 3 files changed, 211 insertions(+), 510 deletions(-) delete mode 100644 src/lua/core/textgpu_new.lua diff --git a/include/luares.h b/include/luares.h index 33b8601..f754bac 100644 --- a/include/luares.h +++ b/include/luares.h @@ -13,7 +13,6 @@ extern char lua_init[]; extern char lua_internet[]; extern char lua_sandbox[]; extern char lua_textgpu[]; -extern char lua_textgpu_new[]; extern char lua_textgpu_old[]; extern char lua_util_buffer[]; extern char lua_util_color[]; diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index f33870b..9a0ec81 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -1,262 +1,283 @@ local textgpu = {} local mapping = {} +local palette = {} --- generate the mapping +-- generate color mapping -local i = 0 for g=0, 255, 0x24 do - for b=0, 255, 0x40 do + for b=0, 256, 0x40 do for r=0, 255, 0x33 do - mapping[tostring(i)] = (r * 0x10000) + (g * 0x100) + b - i = i + 1 + mapping[#mapping+1] = (math.min(r, 255) * 0x10000) + + (math.min(g, 255) * 0x100) + math.min(b, 255) end end end ---[[local nw = io.write -io.write = function(...) - nw(...) - io.flush() - native.sleep(20000) -end]]-- +for i=0, 15, 1 do + mapping[#mapping+1] = (i+1) * 0x0f0f0f + palette[i] = (i+1) * 0x0f0f0f +end local write = io.write local flush = io.flush -local background = "\0" -local foreground = "\255" +local background = 1 +local foreground = 256 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 +local function prep(w, h) + local tl = string.rep(" ", w) + local bb = string.rep("\0", w) + local fb = string.rep("\255", w) + + for i=1, h, 1 do + tbuffer[i] = tl + bbuffer[i] = bb + fbuffer[i] = fb end end -local usub -local function insertString(main, sub, at) - checkArg(1, main, "string") - checkArg(2, sub, "string") - checkArg(3, at, "number") +local fg = 256 +local bg = 1 +local w, h = 1, 1 - return usub(main, 1, at - 1) - .. sub .. usub(main, at + (utf8.len(sub) or 0)) +local unsub +local function set(x, y, text, f, b) + if x > w or x < 1 or y > h or y < 1 or not tbuffer[y] then + error("index out of bounds: " .. y, 3) + end + f = f or fg + b = b or bg + local len = utf8.len(text) + if x + len > w then + text = unsub(text, 1, -1 - ((x + len) - w)) + end + tbuffer[y] = tbuffer[y]:sub(1, x - 1) .. + text .. tbuffer[y]:sub(x + len) + if type(f) == "string" then + fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. + f .. fbuffer[y]:sub(x + len) + else + fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. + string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len) + end + if type(b) == "string" then + bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. + b .. bbuffer[y]:sub(x + len) + else + bbuffer[y] = fbuffer[y]:sub(1, x - 1) .. + string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len) + end + local F, B = mapping[f], mapping[b] + write("\27[38;2;", F&0xFF0000, ";", F&0x00FF00, ";", F&0x0000FF, "m") + write("\27[48;2;", B&0xFF0000, ";", B&0x00FF00, ";", B&0x0000FF, "m") + write("\27[", x, ";", y, "H", text) +end + +local function fullRefresh() + for i=1, h, 1 do + local text = tbuffer[i] + local fgt = fbuffer[i] + local bgt = bbuffer[i] + local pb, pf + fgt = fgt:gsub("()(.)", function(n, fc) + local bc, tc = bgt:sub(n,n), text:sub(n,n) + local str = "" + if bc ~= pb then + pb = bc + local B = mapping[bc] + str = str .. string.format("\27[48;2;%d;%d;%dm", + B&0xFF0000, B&0x00FF00, B&0x0000FF) + end + if fc ~= pf then + pf = fc + local F = mapping[fc] + str = str .. string.format("\27[38;2;%d;%d;%dm", + F&0xFF0000, F&0x00FF00, F&0x0000FF) + end + str = str .. tc + return str + end) + write("\27[", h, ";1H", fgt) + flush() + end +end + +local function get(x, y, len) + if x < 1 or x > w or y < 1 or y > h then + error("index out of bounds: " .. y, 3) + end + len = (len or 1) - 1 + local txt = unsub(tbuffer[y], x, x + len) + if len == 0 then + return text, + mapping[fbuffer[y]:sub(x, x):byte() + 1], + mapping[bbuffer[y]:sub(x, x):byte() + 1] + else + return text, fbuffer[y]:sub(x, x + len), bbuffer[y]:sub(x, x + len) + end end function textgpu.start() - usub = modules.sandbox.unicode.sub - local _height = 0 + unsub = modules.sandbox.unicode.sub local gpu = {} - function gpu.bind() return false, "This is static bound gpu" end - function gpu.setBackground(color, isPaletteIndex) + + function gpu.setForeground(color, ispalette) checkArg(1, color, "number") - checkArg(2, isPaletteIndex, "boolean", "nil") - if isPaletteIndex then - return --TODO: Maybe? + checkArg(2, ispalette, "boolean", "nil") + if ispalette then + if not palette[color] then + error("invalid palette index", 2) + end + color = palette[color] end - local old = background - background = tostring(math.floor(modules.color.nearest(color, mapping))) - write("\x1b[48;5;" .. background:byte() .. "m") - flush() - return mapping[old] + local index = math.floor(modules.color.nearest(color, mapping)) + fg = index or fg + return true end - function gpu.setForeground(color, isPaletteIndex) + + function gpu.setBackground(color, ispalette) checkArg(1, color, "number") - checkArg(2, isPaletteIndex, "boolean", "nil") - if isPaletteIndex then - return --TODO: Maybe? + checkArg(2, ispalette, "boolean", "nil") + if ispalette then + if not palette[color] then + error("invalid palette index", 2) + end + color = palette[color] end - local old = foreground - foreground = tostring(math.floor(modules.color.nearest(color, mapping))) - write("\x1b[38;5;" .. foreground:byte() .. "m") - flush() - return mapping[old] + local index = math.floor(modules.color.nearest(color, mapping)) + bg = index or bg + return true end - function gpu.getBackground() - return mapping[background], false + + function gpu.setPaletteColor(c, v) + checkArg(1, c, "number") + checkArg(2, v, "number") + if not palette[c] then + error("invalid palette index", 2) + end + palette[c] = v end + + function gpu.getPaletteColor(c) + checkArg(1, c, "number") + if not palette[c] then + error("invalid palette index", 2) + end + return palette[c] + end + function gpu.getForeground() - return mapping[foreground], false + return mapping[fg] end - function gpu.getPaletteColor() - return nil - end - function gpu.setPaletteColor() - return nil - end - function gpu.maxDepth() - return 3 - end - function gpu.setDepth() - return false + + function gpu.getBackground() + return mapping[bg] end + function gpu.getDepth() - return 3 + return 4 end - function gpu.maxResolution() - return termutils.getSize() + + function gpu.maxDepth() + return 4 end + + function gpu.setDepth() + return true + end + function gpu.getResolution() return termutils.getSize() end - function gpu.getViewport() - return termutils.getSize() + + function gpu.setResolution() + return false 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" + + gpu.maxResolution = gpu.getResolution + gpu.getViewport = gpu.getResolution + gpu.setViewport = gpu.setResolution + + function gpu.set(x, y, text, vert) + checkArg(1, x, "number") + checkArg(2, y, "number") + checkArg(3, text, "string") + checkArg(4, vert, "boolean", "nil") + if vert then + local i = 1 + local len = utf8.len(text) + while i <= len do + set(x, y + i - 1, unsub(text, i, i)) + i = i + 1 + end + return true + else + set(x, y, text) + end 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)] + return get(x, y) 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[48;5;" .. bg:byte() .. "m\x1b[38;5;" .. fg:byte() .. "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[48;5;" .. bg:byte() .. "m\x1b[38;5;" .. fg:byte() .. "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 + function gpu.fill(x, y, W, H, c) + checkArg(1, x, "number") + checkArg(1, y, "number") + checkArg(1, W, "number") + checkArg(1, H, "number") + checkArg(1, c, "string") + c = unsub(c, 1, 1) + if #c == 0 then return true end + local str = c:rep(W) + for i=1, h, 1 do + set(x, y + i - 1, str) end - write("\x1b[48;5;" .. background:byte() .. "m") - write("\x1b[38;5;" .. foreground:byte() .. "m") - flush() return true end - function gpu.fill(x, y, w, h, ch) + + function gpu.copy(x, y, W, H, xd, yd) 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 + checkArg(3, W, "number") + checkArg(4, H, "number") + checkArg(5, xd, "number") + checkArg(6, yd, "number") + local start, stop, step + if yd > 0 then -- moving up - copy from the top down + start, stop, step = y, y + H, 1 + else -- moving down - copy from the bottom up + start, stop, step = y + H, y, -1 end + for i=start, stop, step do + local str, fstr, bstr = get(x, i, W) + set(x + xd, i + yd, str, fstr, bstr) + end + fullRefresh() return true end local screenAddr - function gpu.getScreen() return screenAddr end + function gpu.bind() 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) + + w, h = gpu.getResolution() + prep(w, h) + gpu.setForeground(0xFFFFFF) gpu.setBackground(0x000000) diff --git a/src/lua/core/textgpu_new.lua b/src/lua/core/textgpu_new.lua deleted file mode 100644 index 810a4e6..0000000 --- a/src/lua/core/textgpu_new.lua +++ /dev/null @@ -1,319 +0,0 @@ -local textgpu = {} - -local write = io.write -local flush = io.flush - -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\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 - fbuffer[i] = fbline - 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) or "") - .. 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 - if color > 15 or color < 0 then - error("invalid palette index", 2) - end - return palette[color] - end - local old = background - background = color -- tostring(math.floor(modules.color.nearest(color, mapping))) - setBackground(background) - --write("\x1b[4" .. background .. "m") - flush() - return old -- mapping[old] - end - function gpu.setForeground(color, isPaletteIndex) - checkArg(1, color, "number") - checkArg(2, isPaletteIndex, "boolean", "nil") - if isPaletteIndex then - if color < 0 or color > 15 then - error("invalid palette index", 2) - end - return palette[color] - end - local old = foreground - foreground = color -- tostring(math.floor(modules.color.nearest(color, mapping))) - setForeground(foreground) - --write("\x1b[3" .. foreground .. "m") - flush() - return old -- mapping[old] - end - function gpu.getBackground() - return mapping[background], false - end - function gpu.getForeground() - return mapping[foreground], false - end - function gpu.getPaletteColor(index) - if index < 0 or index > 15 then - error("invalid palette index", 2) - end - return palette[index] - end - 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 4 - end - function gpu.setDepth() - return true - end - function gpu.getDepth() - return 4 - 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), - 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") - 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], - 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! - 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*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] = string.pack(">I3", background):rep(w) - ftbuf[i] = string.pack(">I3", 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*3-2,j*3):unpack(">I3") ~= bg then - lwrite = true - end - if ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") ~= 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 - 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], - 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*3-2,j*3):unpack(">I3") - fg = ftbuf[i]:sub(j*3-2,j*3):unpack(">I3") - 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 - 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], - 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 - setBackground(background) - setForeground(foreground) - --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 -- 2.30.2 From 7dade89a0e7e5014b18277d98a62a98a45329a4c Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 28 May 2021 13:10:05 -0400 Subject: [PATCH 07/17] textgpu mostly works now --- src/lua/core/textgpu.lua | 64 ++++++++++++++++++++++++++-------------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index 9a0ec81..0ec50ff 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -45,11 +45,16 @@ local fg = 256 local bg = 1 local w, h = 1, 1 -local unsub -local function set(x, y, text, f, b) +local unsub, fullRefresh +local function set(x, y, text, f, b, safe) if x > w or x < 1 or y > h or y < 1 or not tbuffer[y] then - error("index out of bounds: " .. y, 3) + if safe then + return + else + error("index out of bounds: " .. y, 3) + end end + if not text then return end f = f or fg b = b or bg local len = utf8.len(text) @@ -62,6 +67,8 @@ local function set(x, y, text, f, b) fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. f .. fbuffer[y]:sub(x + len) else + local F = mapping[f] + write("\27[38;2;", F&0xFF0000>>16, ";", F&0x00FF00>>8, ";", F&0x0000FF, "m") fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len) end @@ -69,16 +76,16 @@ local function set(x, y, text, f, b) bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. b .. bbuffer[y]:sub(x + len) else - bbuffer[y] = fbuffer[y]:sub(1, x - 1) .. + local B = mapping[b] + write("\27[48;2;", B&0xFF0000>>16, ";", B&0x00FF00>>8, ";", B&0x0000FF, "m") + bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len) end - local F, B = mapping[f], mapping[b] - write("\27[38;2;", F&0xFF0000, ";", F&0x00FF00, ";", F&0x0000FF, "m") - write("\27[48;2;", B&0xFF0000, ";", B&0x00FF00, ";", B&0x0000FF, "m") write("\27[", x, ";", y, "H", text) + flush() end -local function fullRefresh() +fullRefresh = function() for i=1, h, 1 do local text = tbuffer[i] local fgt = fbuffer[i] @@ -89,30 +96,37 @@ local function fullRefresh() local str = "" if bc ~= pb then pb = bc - local B = mapping[bc] + local B = mapping[bc:byte() + 1] str = str .. string.format("\27[48;2;%d;%d;%dm", - B&0xFF0000, B&0x00FF00, B&0x0000FF) + B&0xFF0000>>16, B&0x00FF00>>8, B&0x0000FF) end if fc ~= pf then pf = fc - local F = mapping[fc] + local F = mapping[fc:byte() + 1] str = str .. string.format("\27[38;2;%d;%d;%dm", - F&0xFF0000, F&0x00FF00, F&0x0000FF) + F&0xFF0000>>16, F&0x00FF00>>8, F&0x0000FF) end str = str .. tc return str end) - write("\27[", h, ";1H", fgt) - flush() + write("\27[", i, ";1H", fgt) end + flush() end -local function get(x, y, len) +local function get(x, y, len, safe) if x < 1 or x > w or y < 1 or y > h then - error("index out of bounds: " .. y, 3) + if safe then + return + else + error("index out of bounds: " .. y, 3) + end end len = (len or 1) - 1 - local txt = unsub(tbuffer[y], x, x + len) + if x + len > w then + len = (x + len) - w + end + local text = unsub(tbuffer[y], x, x + len) if len == 0 then return text, mapping[fbuffer[y]:sub(x, x):byte() + 1], @@ -218,6 +232,7 @@ function textgpu.start() return true else set(x, y, text) + return true end end @@ -237,7 +252,7 @@ function textgpu.start() if #c == 0 then return true end local str = c:rep(W) for i=1, h, 1 do - set(x, y + i - 1, str) + set(x, y + i - 1, str, nil, nil, true) end return true end @@ -249,15 +264,19 @@ function textgpu.start() checkArg(4, H, "number") checkArg(5, xd, "number") checkArg(6, yd, "number") + if xd == 0 and yd == 0 then return true end -- hah local start, stop, step - if yd > 0 then -- moving up - copy from the top down + if yd < 0 then -- moving up - copy from the top down start, stop, step = y, y + H, 1 else -- moving down - copy from the bottom up start, stop, step = y + H, y, -1 end for i=start, stop, step do - local str, fstr, bstr = get(x, i, W) - set(x + xd, i + yd, str, fstr, bstr) + local str, fstr, bstr = get(x, i, W, true) + if str and fstr and bstr then + lprint("GPU_COPY: " .. str .. " FROM " .. i .. " TO " .. (i + yd)) + set(x + xd, i + yd, str, fstr, bstr, true) + end end fullRefresh() return true @@ -268,7 +287,7 @@ function textgpu.start() return screenAddr end - function gpu.bind() end + function gpu.bind() --[[STUB]] end if not termutils.init() then return nil, "Cannot initialize terminal based gpu" @@ -277,6 +296,7 @@ function textgpu.start() w, h = gpu.getResolution() prep(w, h) + fullRefresh() gpu.setForeground(0xFFFFFF) gpu.setBackground(0x000000) -- 2.30.2 From 3246aa2d650152c4d7fa53e668cb26fb746f6633 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 28 May 2021 13:19:44 -0400 Subject: [PATCH 08/17] ha! fixed it, mostly... now to make colors work --- src/lua/core/textgpu.lua | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index 0ec50ff..14d7013 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -59,10 +59,11 @@ local function set(x, y, text, f, b, safe) b = b or bg local len = utf8.len(text) if x + len > w then - text = unsub(text, 1, -1 - ((x + len) - w)) + --len = (x + len) - w + --text = unsub(text, 1, len) end - tbuffer[y] = tbuffer[y]:sub(1, x - 1) .. - text .. tbuffer[y]:sub(x + len) + tbuffer[y] = unsub(tbuffer[y], 1, x - 1) .. + text .. unsub(tbuffer[y], x + len) if type(f) == "string" then fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. f .. fbuffer[y]:sub(x + len) @@ -81,7 +82,7 @@ local function set(x, y, text, f, b, safe) bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len) end - write("\27[", x, ";", y, "H", text) + write("\27[", y, ";", x, "H", text) flush() end @@ -222,6 +223,7 @@ function textgpu.start() checkArg(2, y, "number") checkArg(3, text, "string") checkArg(4, vert, "boolean", "nil") + vert = false if vert then local i = 1 local len = utf8.len(text) @@ -251,7 +253,7 @@ function textgpu.start() c = unsub(c, 1, 1) if #c == 0 then return true end local str = c:rep(W) - for i=1, h, 1 do + for i=1, H, 1 do set(x, y + i - 1, str, nil, nil, true) end return true -- 2.30.2 From b4fefd4c0f8ae9b99dde79314bf2769e9ed4d673 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 28 May 2021 13:31:02 -0400 Subject: [PATCH 09/17] color works now \o/ --- src/lua/core/textgpu.lua | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index 14d7013..7418943 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -45,6 +45,10 @@ local fg = 256 local bg = 1 local w, h = 1, 1 +local function rgb(i) + return i>>16&0xFF, i>>8&0xFF, i&0xFF +end + local unsub, fullRefresh local function set(x, y, text, f, b, safe) if x > w or x < 1 or y > h or y < 1 or not tbuffer[y] then @@ -69,7 +73,8 @@ local function set(x, y, text, f, b, safe) f .. fbuffer[y]:sub(x + len) else local F = mapping[f] - write("\27[38;2;", F&0xFF0000>>16, ";", F&0x00FF00>>8, ";", F&0x0000FF, "m") + local r, g, _b = rgb(F) + write("\27[38;2;", r, ";", g, ";", _b, "m") fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len) end @@ -78,7 +83,8 @@ local function set(x, y, text, f, b, safe) b .. bbuffer[y]:sub(x + len) else local B = mapping[b] - write("\27[48;2;", B&0xFF0000>>16, ";", B&0x00FF00>>8, ";", B&0x0000FF, "m") + local r, g, _b = rgb(B) + write("\27[48;2;", r, ";", g, ";", _b, "m") bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len) end @@ -99,13 +105,13 @@ fullRefresh = function() pb = bc local B = mapping[bc:byte() + 1] str = str .. string.format("\27[48;2;%d;%d;%dm", - B&0xFF0000>>16, B&0x00FF00>>8, B&0x0000FF) + rgb(B)) end if fc ~= pf then pf = fc local F = mapping[fc:byte() + 1] str = str .. string.format("\27[38;2;%d;%d;%dm", - F&0xFF0000>>16, F&0x00FF00>>8, F&0x0000FF) + rgb(F)) end str = str .. tc return str @@ -276,7 +282,6 @@ function textgpu.start() for i=start, stop, step do local str, fstr, bstr = get(x, i, W, true) if str and fstr and bstr then - lprint("GPU_COPY: " .. str .. " FROM " .. i .. " TO " .. (i + yd)) set(x + xd, i + yd, str, fstr, bstr, true) end end -- 2.30.2 From ecdc855ee0d84f9b1d28fc8467a1f19b23809933 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 28 May 2021 20:57:45 -0400 Subject: [PATCH 10/17] small scrolling optimization to textgpu --- src/lua/core/textgpu.lua | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index 7418943..f66946b 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -50,7 +50,7 @@ local function rgb(i) end local unsub, fullRefresh -local function set(x, y, text, f, b, safe) +local function set(x, y, text, f, b, safe, noref) if x > w or x < 1 or y > h or y < 1 or not tbuffer[y] then if safe then return @@ -72,9 +72,11 @@ local function set(x, y, text, f, b, safe) fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. f .. fbuffer[y]:sub(x + len) else - local F = mapping[f] - local r, g, _b = rgb(F) - write("\27[38;2;", r, ";", g, ";", _b, "m") + if not noref then + local F = mapping[f] + local r, g, _b = rgb(F) + write("\27[38;2;", r, ";", g, ";", _b, "m") + end fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len) end @@ -82,14 +84,18 @@ local function set(x, y, text, f, b, safe) bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. b .. bbuffer[y]:sub(x + len) else - local B = mapping[b] - local r, g, _b = rgb(B) - write("\27[48;2;", r, ";", g, ";", _b, "m") + if not noref then + local B = mapping[b] + local r, g, _b = rgb(B) + write("\27[48;2;", r, ";", g, ";", _b, "m") + end bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len) end - write("\27[", y, ";", x, "H", text) - flush() + if not noref then + write("\27[", y, ";", x, "H", text) + flush() + end end fullRefresh = function() @@ -282,7 +288,7 @@ function textgpu.start() for i=start, stop, step do local str, fstr, bstr = get(x, i, W, true) if str and fstr and bstr then - set(x + xd, i + yd, str, fstr, bstr, true) + set(x + xd, i + yd, str, fstr, bstr, true, true) end end fullRefresh() -- 2.30.2 From 8260c8f59ff6dcf692fecd6505ae57656763514e Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 16:25:09 -0400 Subject: [PATCH 11/17] add basic support for real arrow key thingos --- src/lua/core/computer.lua | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index 4fa33e7..2697daf 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -97,10 +97,27 @@ local asciitr = { [127] = 8, } +local escmap = { + A = 200, -- up + B = 208, -- down + C = 205, -- right + D = 203, -- left +} + +local inesc = 0 function computer.signalTransformers.key_down(s, a, ascii, key, user) if key ~= -1 then return s, a, ascii, key, user end + if ascii == 27 then + inesc = true + elseif inesc then + if ascii < 48 and ascii > 57 and ascii ~= 59 then + inesc = false + key = escmap[ascii] or 0 + ascii = 0 + end + end return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user end -- 2.30.2 From 300e2d1190dcb32bdfed3c85c70d7ce8e5fb26f3 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 16:27:14 -0400 Subject: [PATCH 12/17] theoretically should be full support now --- src/lua/core/computer.lua | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index 2697daf..b11172a 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -111,11 +111,14 @@ function computer.signalTransformers.key_down(s, a, ascii, key, user) end if ascii == 27 then inesc = true + return nil elseif inesc then if ascii < 48 and ascii > 57 and ascii ~= 59 then inesc = false key = escmap[ascii] or 0 ascii = 0 + else + return nil end end return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user @@ -125,13 +128,28 @@ function computer.signalTransformers.key_up(s, a, ascii, key, user) if key ~= -1 then return s, a, ascii, key, user end + if ascii == 27 then + inesc = true + return nil + elseif inesc then + if ascii < 48 and ascii > 57 and ascii ~= 59 then + inesc = false + key = escmap[ascii] or 0 + ascii = 0 + else + return nil + end + end return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user end ----- function api.pushSignal(s, ...) - signalQueue[#signalQueue + 1] = {computer.signalTransformers[s](s, ...)} + local result = table.pack(computer.signalTransformers[s](s, ...)) + if result.n == 0 then return end + result.n = nil + signalQueue[#signalQueue + 1] = result end function api.pullSignal(timeout) -- 2.30.2 From 193afd38539bc0e39c37778b303ada2f6cf7aa78 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 16:27:42 -0400 Subject: [PATCH 13/17] forgot [ --- src/lua/core/computer.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index b11172a..b1607dc 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -113,7 +113,7 @@ function computer.signalTransformers.key_down(s, a, ascii, key, user) inesc = true return nil elseif inesc then - if ascii < 48 and ascii > 57 and ascii ~= 59 then + if ascii < 48 and ascii > 57 and ascii ~= 59 and ascii ~= 91 then inesc = false key = escmap[ascii] or 0 ascii = 0 @@ -132,7 +132,7 @@ function computer.signalTransformers.key_up(s, a, ascii, key, user) inesc = true return nil elseif inesc then - if ascii < 48 and ascii > 57 and ascii ~= 59 then + if ascii < 48 and ascii > 57 and ascii ~= 59 and ascii ~= 91 then inesc = false key = escmap[ascii] or 0 ascii = 0 -- 2.30.2 From 4331bdf4825446c73d254d3ea90ba883ced15c0d Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 16:40:00 -0400 Subject: [PATCH 14/17] arrow-key signals have been fixed. not in the best way possible, but they have been fixed. --- src/lua/core/computer.lua | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index b1607dc..a6f8e73 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -98,23 +98,23 @@ local asciitr = { } local escmap = { - A = 200, -- up - B = 208, -- down - C = 205, -- right - D = 203, -- left + [65] = 200, -- up + [66] = 208, -- down + [67] = 205, -- right + [68] = 203, -- left } -local inesc = 0 +local inesc_down = false function computer.signalTransformers.key_down(s, a, ascii, key, user) if key ~= -1 then return s, a, ascii, key, user end if ascii == 27 then - inesc = true + inesc_down = true return nil - elseif inesc then - if ascii < 48 and ascii > 57 and ascii ~= 59 and ascii ~= 91 then - inesc = false + elseif inesc_down then + if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then + inesc_down = false key = escmap[ascii] or 0 ascii = 0 else @@ -124,16 +124,17 @@ function computer.signalTransformers.key_down(s, a, ascii, key, user) return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user end +local inesc_up = false function computer.signalTransformers.key_up(s, a, ascii, key, user) if key ~= -1 then return s, a, ascii, key, user end if ascii == 27 then - inesc = true + inesc_up = true return nil - elseif inesc then - if ascii < 48 and ascii > 57 and ascii ~= 59 and ascii ~= 91 then - inesc = false + elseif inesc_up then + if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then + inesc_up = false key = escmap[ascii] or 0 ascii = 0 else @@ -147,7 +148,7 @@ end function api.pushSignal(s, ...) local result = table.pack(computer.signalTransformers[s](s, ...)) - if result.n == 0 then return end + if result.n == 0 or not result[1] then return end result.n = nil signalQueue[#signalQueue + 1] = result end -- 2.30.2 From b16fa6aeb7c7efa2b513c3c9a38e7fb723b5ff08 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 16:43:46 -0400 Subject: [PATCH 15/17] there is now a 100ms timeout so it shouldn't get stuck in escape mode for more than 100ms **ever** --- src/lua/core/computer.lua | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index a6f8e73..4e32102 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -110,15 +110,17 @@ function computer.signalTransformers.key_down(s, a, ascii, key, user) return s, a, ascii, key, user end if ascii == 27 then - inesc_down = true + inesc_down = native.uptime() / 1000 return nil elseif inesc_down then if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then inesc_down = false key = escmap[ascii] or 0 ascii = 0 - else + elseif native.uptime() - inesc_down > 100 then -- 100ms timeout after {ESC} return nil + else + inesc_down = false end end return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user @@ -130,15 +132,17 @@ function computer.signalTransformers.key_up(s, a, ascii, key, user) return s, a, ascii, key, user end if ascii == 27 then - inesc_up = true + inesc_up = native.uptime() / 1000 return nil elseif inesc_up then if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then inesc_up = false key = escmap[ascii] or 0 ascii = 0 - else + elseif native.uptime() - inesc_up > 100 then -- 100ms timeout after {ESC} return nil + else + inesc_up = false end end return s, a, math.floor(asciitr[ascii] or ascii), keymap[ascii] or key, user -- 2.30.2 From f847f6a2caf975eda3a3fc21515e003ac6694d60 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 17:14:29 -0400 Subject: [PATCH 16/17] fixed an incompatibility in textgpu; fixed ctrl+KEY under OpenOS --- src/lua/core/computer.lua | 80 +++++++++++++++++++++++++-------------- src/lua/core/textgpu.lua | 6 ++- 2 files changed, 56 insertions(+), 30 deletions(-) diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index 4e32102..f90c173 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -62,30 +62,30 @@ local keymap = { [0x60 + 0x01] = 0x1E, [0x60 + 0x02] = 0x30, - [0x60 + 0x04] = 0x2E, - [0x60 + 0x05] = 0x20, - [0x60 + 0x06] = 0x12, - [0x60 + 0x07] = 0x21, - [0x60 + 0x08] = 0x22, - [0x60 + 0x09] = 0x23, - [0x60 + 0x0A] = 0x17, - [0x60 + 0x0B] = 0x24, - [0x60 + 0x0C] = 0x25, - [0x60 + 0x0D] = 0x26, - [0x60 + 0x0E] = 0x32, - [0x60 + 0x0F] = 0x31, - [0x60 + 0x11] = 0x18, - [0x60 + 0x12] = 0x19, - [0x60 + 0x13] = 0x10, - [0x60 + 0x14] = 0x13, - [0x60 + 0x15] = 0x1F, - [0x60 + 0x16] = 0x14, - [0x60 + 0x17] = 0x16, - [0x60 + 0x18] = 0x2F, - [0x60 + 0x19] = 0x11, - [0x60 + 0x1A] = 0x2D, - [0x60 + 0x1B] = 0x15, - [0x60 + 0x1C] = 0x2C, + [0x60 + 0x03] = 0x2E, + [0x60 + 0x04] = 0x20, + [0x60 + 0x05] = 0x12, + [0x60 + 0x06] = 0x21, + [0x60 + 0x07] = 0x22, + [0x60 + 0x08] = 0x23, + [0x60 + 0x09] = 0x17, + [0x60 + 0x0A] = 0x24, + [0x60 + 0x0B] = 0x25, + [0x60 + 0x0C] = 0x26, + [0x60 + 0x0D] = 0x32, + [0x60 + 0x0E] = 0x31, + [0x60 + 0x0F] = 0x18, + [0x60 + 0x10] = 0x19, + [0x60 + 0x11] = 0x10, + [0x60 + 0x12] = 0x13, + [0x60 + 0x13] = 0x1F, + [0x60 + 0x13] = 0x14, + [0x60 + 0x14] = 0x16, + [0x60 + 0x16] = 0x2F, + [0x60 + 0x17] = 0x11, + [0x60 + 0x18] = 0x2D, + [0x60 + 0x19] = 0x15, + [0x60 + 0x1A] = 0x2C, [13] = 28, --Return key [127] = 14, --backspace @@ -105,21 +105,33 @@ local escmap = { } local inesc_down = false +local esc_down_ctrl = false function computer.signalTransformers.key_down(s, a, ascii, key, user) if key ~= -1 then return s, a, ascii, key, user end if ascii == 27 then - inesc_down = native.uptime() / 1000 + inesc_down = native.uptime() return nil + elseif ascii < 27 and ascii ~= 8 and ascii ~= 13 and ascii ~= 9 then + signalQueue[#signalQueue + 1] = {s, a, 0, 29, user} + key = keymap[ascii + 96] or -1 elseif inesc_down then if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then inesc_down = false key = escmap[ascii] or 0 - ascii = 0 + if not esc_down_ctrl then + --ascii = math.max(0, ascii - 96) + else + ascii = 0 + end + esc_down_ctrl = false + elseif ascii == 91 then + esc_down_ctrl = true elseif native.uptime() - inesc_down > 100 then -- 100ms timeout after {ESC} return nil else + esc_down_ctrl = false inesc_down = false end end @@ -127,21 +139,33 @@ function computer.signalTransformers.key_down(s, a, ascii, key, user) end local inesc_up = false +local esc_up_ctrl = false function computer.signalTransformers.key_up(s, a, ascii, key, user) if key ~= -1 then return s, a, ascii, key, user end if ascii == 27 then - inesc_up = native.uptime() / 1000 + inesc_up = native.uptime() return nil + elseif ascii < 27 and ascii ~= 8 and ascii ~= 13 and ascii ~= 9 then + signalQueue[#signalQueue+1] = {s, a, 0, 29, user} + key = keymap[ascii + 96] or 0 elseif inesc_up then if (ascii < 48 or ascii > 57) and ascii ~= 59 and ascii ~= 91 then inesc_up = false key = escmap[ascii] or 0 - ascii = 0 + if not esc_up_ctrl then + --ascii = math.max(0, ascii - 96) + else + ascii = 0 + end + esc_up_ctrl = false + elseif ascii == 91 then + esc_up_ctrl = true elseif native.uptime() - inesc_up > 100 then -- 100ms timeout after {ESC} return nil else + esc_up_ctrl = false inesc_up = false end end diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index f66946b..096bd6f 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -156,6 +156,7 @@ function textgpu.start() function gpu.setForeground(color, ispalette) checkArg(1, color, "number") checkArg(2, ispalette, "boolean", "nil") + local ret = color if ispalette then if not palette[color] then error("invalid palette index", 2) @@ -164,12 +165,13 @@ function textgpu.start() end local index = math.floor(modules.color.nearest(color, mapping)) fg = index or fg - return true + return ret, ispalette end function gpu.setBackground(color, ispalette) checkArg(1, color, "number") checkArg(2, ispalette, "boolean", "nil") + local ret = color if ispalette then if not palette[color] then error("invalid palette index", 2) @@ -178,7 +180,7 @@ function textgpu.start() end local index = math.floor(modules.color.nearest(color, mapping)) bg = index or bg - return true + return ret, ispalette end function gpu.setPaletteColor(c, v) -- 2.30.2 From c6a0ecd8a430f61606052d66ceac01b9dead05c7 Mon Sep 17 00:00:00 2001 From: ocawesome101 Date: Fri, 4 Jun 2021 20:11:23 -0400 Subject: [PATCH 17/17] fix textgpu somehow getting *really* long buffer lines, which broke things sometimes --- src/lua/core/textgpu.lua | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index 096bd6f..acb2732 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -78,7 +78,7 @@ local function set(x, y, text, f, b, safe, noref) write("\27[38;2;", r, ";", g, ";", _b, "m") end fbuffer[y] = fbuffer[y]:sub(1, x - 1) .. - string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len) + string.rep(string.char(f - 1), len) .. fbuffer[y]:sub(x + len) end if type(b) == "string" then bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. @@ -92,6 +92,10 @@ local function set(x, y, text, f, b, safe, noref) bbuffer[y] = bbuffer[y]:sub(1, x - 1) .. string.rep(string.char(b - 1), len) .. bbuffer[y]:sub(x + len) end + -- clamp buffers + tbuffer[y] = unsub(tbuffer[y], 1, w) + fbuffer[y] = fbuffer[y]:sub(1, w) + bbuffer[y] = bbuffer[y]:sub(1, w) if not noref then write("\27[", y, ";", x, "H", text) flush() @@ -103,6 +107,7 @@ fullRefresh = function() local text = tbuffer[i] local fgt = fbuffer[i] local bgt = bbuffer[i] + --native.log("UPDATE " .. i .. ": \"" .. text .. "\"") local pb, pf fgt = fgt:gsub("()(.)", function(n, fc) local bc, tc = bgt:sub(n,n), text:sub(n,n) @@ -289,7 +294,8 @@ function textgpu.start() end for i=start, stop, step do local str, fstr, bstr = get(x, i, W, true) - if str and fstr and bstr then + --native.log("COPY " .. i .. " (" .. (str or "") .. ") to " .. (i + yd)) + if str then-- and fstr and bstr then set(x + xd, i + yd, str, fstr, bstr, true, true) end end -- 2.30.2