diff --git a/include/luares.h b/include/luares.h index 76f9769..11e6ff0 100644 --- a/include/luares.h +++ b/include/luares.h @@ -5,5 +5,7 @@ extern char lua_component[]; extern char lua_computer[]; extern char lua_init[]; extern char lua_sandbox[]; +extern char lua_textgpu[]; +extern char lua_util_color[]; extern char lua_util_random[]; #endif diff --git a/include/lupi.h b/include/lupi.h index 62f43d2..6c1420b 100644 --- a/include/lupi.h +++ b/include/lupi.h @@ -4,6 +4,11 @@ #ifndef LUPI_H #define LUPI_H +//TODO: move to utils +#define pushstuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3) +#define pushctuple(state, name, value) lua_pushstring((state), (name)); lua_pushcfunction((state), (value)); lua_settable((state), -3) + void run_init(); void setup_modules(lua_State *L); +void termutils_start(lua_State *L); #endif diff --git a/src/c/modules.c b/src/c/modules.c index bb3df71..76de31e 100644 --- a/src/c/modules.c +++ b/src/c/modules.c @@ -5,18 +5,16 @@ #include #include -//TODO: move to utils -#define pushtuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3) - - void setup_modules(lua_State *L) { lua_createtable (L, 0, 1); - pushtuple(L, "boot", lua_boot); - pushtuple(L, "component", lua_component); - pushtuple(L, "computer", lua_computer); - pushtuple(L, "sandbox", lua_sandbox); - pushtuple(L, "random", lua_util_random); + pushstuple(L, "boot", lua_boot); + pushstuple(L, "component", lua_component); + pushstuple(L, "computer", lua_computer); + pushstuple(L, "sandbox", lua_sandbox); + pushstuple(L, "textgpu", lua_textgpu); + pushstuple(L, "color", lua_util_color); + pushstuple(L, "random", lua_util_random); lua_setglobal(L, "moduleCode"); } \ No newline at end of file diff --git a/src/c/run.c b/src/c/run.c index 029010d..835290b 100644 --- a/src/c/run.c +++ b/src/c/run.c @@ -8,8 +8,11 @@ void run_init() { lua_State *L; L = luaL_newstate(); - luaL_openlibs(L); - setup_modules(L); + + luaL_openlibs (L); + setup_modules (L); + termutils_start (L); + int status = luaL_loadstring(L, lua_init); if (status) { fprintf(stderr, "Couldn't load init: %s\n", lua_tostring(L, -1)); diff --git a/src/c/termutils.c b/src/c/termutils.c new file mode 100644 index 0000000..73c36d5 --- /dev/null +++ b/src/c/termutils.c @@ -0,0 +1,34 @@ +#include "lupi.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static void handle_winch(int sig){ + signal(SIGWINCH, SIG_IGN); + + //FIXME: Prerelease: Implement + signal(SIGWINCH, handle_winch); +} + +static int l_get_term_sz (lua_State *L) { + struct winsize w; + ioctl(STDOUT_FILENO, TIOCGWINSZ, &w); + lua_pushnumber(L, w.ws_col); + lua_pushnumber(L, w.ws_row); + return 2; +} + + +void termutils_start(lua_State *L) { + signal(SIGWINCH, handle_winch); + + lua_createtable (L, 0, 1); + pushctuple(L, "getSize", l_get_term_sz); + + lua_setglobal(L, "termutils"); +} \ No newline at end of file diff --git a/src/lua/core/boot.lua b/src/lua/core/boot.lua index 4c4bb3b..15a4053 100644 --- a/src/lua/core/boot.lua +++ b/src/lua/core/boot.lua @@ -1,6 +1,10 @@ local boot = {} function boot.boot() + local gpu = modules.component.api.proxy(modules.component.api.list("gpu", true)()) + local w, h = gpu.getResolution() + print("r= " .. tostring(w) .. " " .. tostring(h)) + gpu.fill(0, 0, w, h, " ") print("LuPI L2 INIT") print("FIXME: boot stub") error("Unable to boot") diff --git a/src/lua/core/component.lua b/src/lua/core/component.lua index a34324b..f48387d 100644 --- a/src/lua/core/component.lua +++ b/src/lua/core/component.lua @@ -18,7 +18,7 @@ function api.register(address, ctype, proxy, doc) checkArg(2, ctype, "string") checkArg(3, proxy, "table") if type(address) ~= "string" then - address = random.uuid() + address = modules.random.uuid() end if components[address] ~= nil then return nil, "component already at address" @@ -28,12 +28,13 @@ function api.register(address, ctype, proxy, doc) components[address].proxy = {} for k,v in pairs(proxy) do if type(v) == "function" then - components[address].proxy = setmetatable({name=k,address=address}, componentCallback) + print("Cfunc " .. k) + components[address].proxy[k] = setmetatable({name=k,address=address}, componentCallback) else - components[address].proxy = v + components[address].proxy[k] = v end end - computer.pushSignal("component_added", address, ctype) + modules.computer.api.pushSignal("component_added", address, ctype) return true end @@ -44,7 +45,7 @@ function api.unregister(address) end local ctype = components[address].type components[address] = nil - computer.pushSignal("component_removed", address, ctype) + modules.computer.api.pushSignal("component_removed", address, ctype) return true end diff --git a/src/lua/core/computer.lua b/src/lua/core/computer.lua index 4b3d230..8ddae3e 100644 --- a/src/lua/core/computer.lua +++ b/src/lua/core/computer.lua @@ -1,7 +1,13 @@ local computer = {} +local api = {} +computer.api = api function computer.prepare( ... ) end +function api.pushSignal(...) + --FIXME: ASAP: Implement +end + return computer \ No newline at end of file diff --git a/src/lua/core/init.lua b/src/lua/core/init.lua index d12af33..3154e8c 100644 --- a/src/lua/core/init.lua +++ b/src/lua/core/init.lua @@ -1,4 +1,4 @@ -local function checkArg(n, have, ...) +function checkArg(n, have, ...) have = type(have) local function check(want, ...) if not want then @@ -36,8 +36,13 @@ end --Load modules loadModule("random") +loadModule("color") + loadModule("component") loadModule("computer") + +loadModule("textgpu") + loadModule("sandbox") loadModule("boot") @@ -45,4 +50,5 @@ loadModule("boot") modules.component.prepare() modules.computer.prepare() +modules.textgpu.start() modules.boot.boot() diff --git a/src/lua/core/textgpu.lua b/src/lua/core/textgpu.lua new file mode 100644 index 0000000..5c55386 --- /dev/null +++ b/src/lua/core/textgpu.lua @@ -0,0 +1,121 @@ +local textgpu = {} + +local mapping = { + ["0"] = 0x000000, + ["1"] = 0xFF0000, + ["2"] = 0x00FF00, + ["3"] = 0xFFFF00, + ["4"] = 0x0000FF, + ["5"] = 0xFF00FF, + ["6"] = 0x00FFFF, + ["7"] = 0xFFFFFF, +} + +local background = "0" +local foreground = "0" + +function textgpu.start() + local gpu = {} + function gpu.bind() return false, "This is static bound gpu" end + function gpu.getScreen() return "n/a" end + function gpu.setBackground(color, isPaletteIndex) + checkArg(1, color, "number") + checkArg(2, isPaletteIndex, "boolean", "nil") + if isPaletteIndex then + return --TODO: Maybe? + end + background = modules.color.nearest(color, mapping) + io.write("\x1b[4" .. background .. "m") + end + function gpu.setForeground(color, isPaletteIndex) + checkArg(1, color, "number") + checkArg(2, isPaletteIndex, "boolean", "nil") + if isPaletteIndex then + return --TODO: Maybe? + end + background = modules.color.nearest(color, mapping) + io.write("\x1b[3" .. background .. "m") + 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.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") + --FIXME: ASAP: Implement + return " " + 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") + if not vertical then + io.write("\x1b[" .. y .. ";" .. x .. "H" .. value) + else + io.write("\x1b[" .. y .. ";" .. x .. "H") + value:gsub(".", function(c) + io.write(c .. "\x1b[D\x1b[B") + end) + end + return true + end + function gpu.copy(x, y, w, h, tx, ty) + 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 + 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 = ch:sub(1, 1):rep(w) + for i=1, h do + gpu.set(x, y + i - 1, ch) + end + return true + end + + gpu.setForeground(0xFFFFFF) + gpu.setBackground(0x000000) + + modules.component.api.register(nil, "gpu", gpu) +end + +return textgpu \ No newline at end of file diff --git a/src/lua/core/util/color.lua b/src/lua/core/util/color.lua new file mode 100644 index 0000000..dc9f582 --- /dev/null +++ b/src/lua/core/util/color.lua @@ -0,0 +1,68 @@ +local color = {} + +function color.rgbToHsv(r, g, b) + local h, s, v + local min, max, delta + min = math.min(r, g, b) + max = math.max(r, g, b) + v = max + delta = max - min + if delta < 0.00001 then + return 0, 0, v + end + if max ~= 0 then + s = delta / max + else + s = 0 + h = -1 + return h, s, v + end + + if r == max then + h = (g - b) / delta + elseif g == max then + h = 2 + (b - r) / delta + else + h = 4 + (r - g) / delta + end + + h = h * 60 + if h < 0 then h = h + 360 end + return h, s, v +end + +function color.hsvToRgb(h, s, v) + local i, f, p, q, t + if s == 0 then + return v, v, v + end + h = h / 60 + i = math.floor(h) + f = h - i + p = v * (1 - s) + q = v * (1 - s * f) + t = v * (1 - s * (1 - f)) + if i == 0 then return v, t, p end + if i == 1 then return q, v, p end + if i == 2 then return p, v, t end + if i == 3 then return p, q, v end + if i == 4 then return t, p, v end + return v, p, q +end + +function color.nearest(to, colors) + local lowest = math.huge + local lowestk = nil + local th, ts, tv = color.rgbToHsv((to & 0xFF0000) >> 16, (to & 0xFF00) >> 8, to & 0xFF) + for k, col in pairs(colors) do + local h, s, v = color.rgbToHsv((col & 0xFF0000) >> 16, (col & 0xFF00) >> 8, col & 0xFF) + local d = math.abs(h - th) + math.abs(s - ts) + math.abs(v - tv) + if d < lowest then + lowest = d + lowestk = k + end + end + return lowestk +end + +return color \ No newline at end of file diff --git a/src/lua/core/util/random.lua b/src/lua/core/util/random.lua index 98947cd..a2217f8 100644 --- a/src/lua/core/util/random.lua +++ b/src/lua/core/util/random.lua @@ -3,7 +3,7 @@ local random = {} function random.uuid() local template ='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' return string.gsub(template, '[xy]', function (c) - local v = (c == 'x') and random(0, 0xf) or random(8, 0xb) + local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb) return string.format('%x', v) end) end