diff --git a/include/luares.h b/include/luares.h index d75a063..c420e98 100644 --- a/include/luares.h +++ b/include/luares.h @@ -9,6 +9,8 @@ extern char lua_filesystem[]; extern char lua_init[]; extern char lua_sandbox[]; extern char lua_textgpu[]; +extern char lua_utf8_utf8data[]; +extern char lua_utf8_utf8[]; extern char lua_util_color[]; extern char lua_util_random[]; #endif diff --git a/scripts/txt2c b/scripts/txt2c index 25b416d..9c4c084 100755 --- a/scripts/txt2c +++ b/scripts/txt2c @@ -5,14 +5,15 @@ # $4 prefix generate() { - LUAFILES="$1/*" - OUTPUTH="$2" - OUTPUTC="$3" - PREFIX="$4" + local LUAFILES="$1/*" + local OUTPUTH="$2" + local OUTPUTC="$3" + local PREFIX="$4" - outname="$(basename "$OUTPUTH")" + local outname="$(basename "$OUTPUTH")" outname="${outname%.*}" - guard=$(echo "$outname" | tr '[:lower:]' '[:upper:]') + + local guard=$(echo "$outname" | tr '[:lower:]' '[:upper:]') guard="$guard""_H" diff --git a/src/c/lnative.c b/src/c/lnative.c index b9c32bf..af03e55 100644 --- a/src/c/lnative.c +++ b/src/c/lnative.c @@ -17,6 +17,8 @@ #include #include + +#ifdef LOGGING void logn (const char *message) { FILE *file; @@ -58,7 +60,11 @@ void logm (const char *message) { fclose(file); } } - +#else +#define logn(m) +#define logi(m) +#define logm(m) +#endif static int l_sleep (lua_State *L) { unsigned int t = lua_tonumber(L, 1); diff --git a/src/c/modules.c b/src/c/modules.c index c890d16..bd6d451 100644 --- a/src/c/modules.c +++ b/src/c/modules.c @@ -18,6 +18,8 @@ void setup_modules(lua_State *L) { pushstuple(L, "textgpu", lua_textgpu); pushstuple(L, "color", lua_util_color); pushstuple(L, "random", lua_util_random); + pushstuple(L, "utf8data", lua_utf8_utf8data); + pushstuple(L, "utf8", lua_utf8_utf8); lua_setglobal(L, "moduleCode"); } \ No newline at end of file diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index c26d69e..e005815 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -6,14 +6,18 @@ function computer.prepare( ... ) end +local signalQueue = {} + function api.pushSignal(...) - --FIXME: ASAP: Implement + signalQueue[#signalQueue + 1] = {...} end function api.pullSignal(timeout) + if signalQueue[1] then return table.remove(signalQueue, 1) end if type(timeout) == "number" then native.sleep(timeout * 1000000); end + if signalQueue[1] then return table.remove(signalQueue, 1) end --print(debug.traceback()) end diff --git a/src/lua/core/init.lua b/src/lua/core/init.lua index 24dfadd..5bed66d 100644 --- a/src/lua/core/init.lua +++ b/src/lua/core/init.lua @@ -22,6 +22,7 @@ deadhooks = {} local function loadModule(name) print("LuPI L1 INIT > Load module > " .. name) + io.flush() --TODO: PRERELEASE: Module sandboxing, preferably secure-ish --TODO: ASAP: Handle load errors if not moduleCode[name] then @@ -30,6 +31,7 @@ local function loadModule(name) local code, reason = load(moduleCode[name], "=Module "..name) if not code then print("Failed loading module " .. name .. ": " .. reason) + io.flush() else modules[name] = code() end @@ -40,6 +42,8 @@ function main() --Utils loadModule("random") loadModule("color") + loadModule("utf8data") + loadModule("utf8") --Core loadModule("component") diff --git a/src/lua/core/sandbox.lua b/src/lua/core/sandbox.lua index 30377c8..4fe4375 100644 --- a/src/lua/core/sandbox.lua +++ b/src/lua/core/sandbox.lua @@ -160,6 +160,24 @@ sandbox = { len = utf8.len, offset = utf8.offset }, + unicode = { + char = utf8.char, + charWidth = function(c) + checkArg(1, c, "string") + return modules.utf8.utf8charbytes(c) + end, + isWide = function(c) + checkArg(1, c, "string") + return modules.utf8.utf8charbytes(c) > 1 + end, + len = utf8.len, + lower = modules.utf8.lower, + reverse = modules.utf8.reverse, + sub = modules.utf8.sub, + upper = modules.utf8.upper, + wlen = utf8.len, --How is it different from len? + --wtrunc? + }, checkArg = checkArg, og = _G } diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua index d49cd38..9ab13ee 100644 --- a/src/lua/core/textgpu.lua +++ b/src/lua/core/textgpu.lua @@ -11,9 +11,36 @@ local mapping = { ["7"] = 0xFFFFFF, } +--[[local nw = io.write +io.write = function(...) + nw(...) + io.flush() + native.sleep(20000) +end]]-- + 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 = modules.utf8.sub +local function insertString(main, sub, at) + return usub(main, 1, at - 1) .. sub .. usub(main, at + utf8.len(sub)) +end + function textgpu.start() local gpu = {} function gpu.bind() return false, "This is static bound gpu" end @@ -24,8 +51,8 @@ function textgpu.start() if isPaletteIndex then return --TODO: Maybe? end - background = modules.color.nearest(color, mapping) - io.write("\x1b[4" .. math.floor(background) .. "m") + background = tostring(math.floor(modules.color.nearest(color, mapping))) + io.write("\x1b[4" .. background .. "m") io.flush() end function gpu.setForeground(color, isPaletteIndex) @@ -34,8 +61,8 @@ function textgpu.start() if isPaletteIndex then return --TODO: Maybe? end - foreground = modules.color.nearest(color, mapping) - io.write("\x1b[3" .. math.floor(foreground) .. "m") + foreground = tostring(math.floor(modules.color.nearest(color, mapping))) + io.write("\x1b[3" .. foreground .. "m") io.flush() end function gpu.getBackground() @@ -84,6 +111,9 @@ function textgpu.start() x = math.floor(x) y = math.floor(y) if not vertical then + 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) io.write("\x1b[" .. y .. ";" .. x .. "H" .. value) else io.write("\x1b[" .. y .. ";" .. x .. "H") @@ -94,15 +124,68 @@ function textgpu.start() io.flush() return true end - function gpu.copy(x, y, w, h, tx, ty) + 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") - --FIXME: ASAP: Implement - return false + local ttbuf = {} + local btbuf = {} + local ftbuf = {} + for i=1, h do + ttbuf[i] = tbuffer[y + i - 1] and tbuffer[y + i - 1]:sub(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) + end + local bg = background + local fg = foreground + + for i=1, h do + local line, linex + local write = false + for j=1, w do + if btbuf[i]:sub(j,j) ~= bg then + bg = btbuf[i]:sub(j,j) + io.write("\x1b[4" .. bg .. "m") + write = true + end + if ftbuf[i]:sub(j,j) ~= fg then + fg = ftbuf[i]:sub(j,j) + io.write("\x1b[3" .. fg .. "m") + write = true + end + if not line then linex = j end + line = (line or "") .. ttbuf[i]:sub(j,j) + if write then + local wx = (tx + linex)|0 + local wy = (ty + y + i - 1)|0 + io.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) + line = nil + linex = nil + write = false + end + end + if line then + local wx = (tx + linex)|0 + local wy = (ty + y + i - 1)|0 + io.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) + line = nil + linex = nil + write = false + end + end + io.write("\x1b[4" .. background .. "m") + io.write("\x1b[3" .. foreground .. "m") + io.flush() + return true end function gpu.fill(x, y, w, h, ch) checkArg(1, x, "number") @@ -118,6 +201,8 @@ function textgpu.start() end io.write("\x1b[?25l") --Disable cursor + local w, h = gpu.getResolution() + prepareBuffers(w, h) gpu.setForeground(0xFFFFFF) gpu.setBackground(0x000000) diff --git a/src/lua/core/utf8/utf8.lua b/src/lua/core/utf8/utf8.lua index 5b496a9..c5d219c 100644 --- a/src/lua/core/utf8/utf8.lua +++ b/src/lua/core/utf8/utf8.lua @@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -- local strbyte, strlen, strsub, type = string.byte, string.len, string.sub, type +local utf8 = {} -- returns the number of bytes used by the UTF-8 character at byte i in s -- also doubles as a UTF-8 character validator @@ -154,6 +155,8 @@ local function utf8charbytes(s, i) end end +utf8.charbytes = utf8charbytes + -- returns the number of characters in a UTF-8 string local function utf8len(s) -- argument checking @@ -173,10 +176,7 @@ local function utf8len(s) return len end --- install in the string library -if not string.utf8len then - string.utf8len = utf8len -end +utf8.len = utf8len -- functions identically to string.sub except that i and j are UTF-8 characters -- instead of bytes @@ -230,10 +230,7 @@ local function utf8sub(s, i, j) return strsub(s, startByte, endByte) end --- install in the string library -if not string.utf8sub then - string.utf8sub = utf8sub -end +utf8.sub = utf8sub -- replace UTF-8 characters based on a mapping table local function utf8replace(s, mapping) @@ -264,23 +261,17 @@ end -- identical to string.upper except it knows about unicode simple case conversions local function utf8upper(s) - return utf8replace(s, utf8_lc_uc) + return utf8replace(s, modules.utf8data.lc_uc) end --- install in the string library -if not string.utf8upper and utf8_lc_uc then - string.utf8upper = utf8upper -end +utf8.upper = utf8upper -- identical to string.lower except it knows about unicode simple case conversions local function utf8lower(s) - return utf8replace(s, utf8_uc_lc) + return utf8replace(s, modules.utf8data.uc_lc) end --- install in the string library -if not string.utf8lower and utf8_uc_lc then - string.utf8lower = utf8lower -end +utf8.lower = utf8lower -- identical to string.reverse except that it supports UTF-8 local function utf8reverse(s) @@ -311,7 +302,6 @@ local function utf8reverse(s) return newstr end --- install in the string library -if not string.utf8reverse then - string.utf8reverse = utf8reverse -end \ No newline at end of file +utf8.reverse = utf8reverse + +return utf8 diff --git a/src/lua/core/utf8/utf8data.lua b/src/lua/core/utf8/utf8data.lua index 07bfda1..0c79123 100644 --- a/src/lua/core/utf8/utf8data.lua +++ b/src/lua/core/utf8/utf8data.lua @@ -1,4 +1,4 @@ -utf8_lc_uc = { +local lc_uc = { ["a"] = "A", ["b"] = "B", ["c"] = "C", @@ -933,7 +933,7 @@ } -utf8_uc_lc = { +local uc_lc = { ["A"] = "a", ["B"] = "b", ["C"] = "c", @@ -1858,3 +1858,4 @@ utf8_uc_lc = { ["𐐧"] = "𐑏", } +return {uc_lc = uc_lc, lc_uc = lc_uc}