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)