diff --git a/include/luares.h b/include/luares.h index d47a749..e8061b9 100644 --- a/include/luares.h +++ b/include/luares.h @@ -5,6 +5,7 @@ extern char lua_component[]; extern char lua_computer[]; extern char lua_debug[]; extern char lua_eeprom[]; +extern char lua_fbgpu[]; extern char lua_filesystem[]; extern char lua_gpio[]; extern char lua_init[]; diff --git a/include/lupi.h b/include/lupi.h index 381c87b..b799a85 100644 --- a/include/lupi.h +++ b/include/lupi.h @@ -17,11 +17,14 @@ void logm(const char *message); #define pushstuple(state, name, value) lua_pushstring((state), (name)); lua_pushstring((state), (value)); lua_settable((state), -3) +typedef unsigned short ushort; + lua_State* getL(); void run_init(); void lupi_init(); void luanative_start(lua_State *L); +void fb_start(lua_State *L); void setup_modules(lua_State *L); void termutils_start(lua_State *L); void internet_start(lua_State *L); diff --git a/include/res.h b/include/res.h index c117410..9fe7e3a 100644 --- a/include/res.h +++ b/include/res.h @@ -1,4 +1,5 @@ #ifndef RES_H #define RES_H extern char res_eepromDefault[]; +extern char res_unifont[]; #endif diff --git a/resources/unifont.bin b/resources/unifont.bin new file mode 100644 index 0000000..822826b Binary files /dev/null and b/resources/unifont.bin differ diff --git a/src/c/fb.c b/src/c/fb.c new file mode 100644 index 0000000..d9b5b82 --- /dev/null +++ b/src/c/fb.c @@ -0,0 +1,503 @@ +#define _XOPEN_SOURCE 500 + +#include "res.h" +#include "lupi.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int fb_ready = 0; +int fb_file; +struct fb_var_screeninfo fb_vinfo; +struct fb_fix_screeninfo fb_finfo; +char *fb_ptr = 0; +char *colbuf = 0; +ushort *chrbuf = 0; +int fb_cw, fb_ch, fb_bpp, fb_bypp, fb_xo, fb_yo, fb_pitch; +int fb_rot = 0; +int palette[256]; +float pal_yuv[768]; + +#define XY_TO_FB(x, y) (((fb_yo + (y)) * fb_pitch) + ((fb_xo + (x)) * fb_bypp)) +#define XY_TO_COLBUF(x, y, z) (((((y) * fb_cw) + (x)) * 2) + (z)) +#define XY_TO_CHRBUF(x, y) (((y) * fb_cw) + (x)) + +static inline int fb_xrot(int x, int y) { + switch (fb_rot) { + default: + return x; + case 1: + return fb_vinfo.xres - y - 1; + case 2: + return fb_vinfo.xres - x - 1; + case 3: + return y; + } +} + +static inline int fb_yrot(int x, int y) { + switch (fb_rot) { + default: + return y; + case 1: + return x; + case 2: + return fb_vinfo.yres - y - 1; + case 3: + return fb_vinfo.yres - x - 1; + } +} + +static inline int fb_cxrot(int x, int y) { + switch (fb_rot) { + default: + return x; + case 1: + return (fb_vinfo.xres >> 4) - y - 1; + case 2: + return (fb_vinfo.xres >> 3) - x - 1; + case 3: + return y; + } +} + +static inline int fb_cyrot(int x, int y) { + switch (fb_rot) { + default: + return y; + case 1: + return x; + case 2: + return (fb_vinfo.yres >> 4) - y - 1; + case 3: + return (fb_vinfo.yres >> 3) - x - 1; + } +} + +static inline float yuv_y(int r, int g, int b) { + float rf = r/255.0f; + float gf = g/255.0f; + float bf = b/255.0f; + return 0.299f * r + 0.587f * g + 0.114f * b; +} +static inline float yuv_u(int r, int g, int b) { + float rf = r/255.0f; + float gf = g/255.0f; + float bf = b/255.0f; + return -0.147f * r - 0.289f * g + 0.436f * b; +} +static inline float yuv_v(int r, int g, int b) { + float rf = r/255.0f; + float gf = g/255.0f; + float bf = b/255.0f; + return 0.615f * r - 0.515f * g - 0.100f * b; +} + +static int l_set_palette (lua_State *L) { + int i = lua_tonumber(L, 1); + int pal = lua_tonumber(L, 2); + if(i >= 0 && i < 256) { + // calculate yuv + int r = (pal >> 16) & 0xFF; + int g = (pal >> 8) & 0xFF; + int b = pal & 0xFF; + pal_yuv[i*3] = yuv_y(r, g, b); + pal_yuv[i*3+1] = yuv_u(r, g, b); + pal_yuv[i*3+2] = yuv_v(r, g, b); + // set palette color + if (fb_bpp == 16) { + palette[i] = + ((r & 0xF8) << 8) | + ((g & 0xFC) << 3) | + ((b & 0xF8) >> 3); + } else { + palette[i] = pal; + } + } + return 0; +} + +static int l_get_nearest (lua_State *L) { + int nck = 0; + float ncv = 1000000; + int i; + int col = lua_tonumber(L, 1); + int r = (col >> 16) & 0xFF; + int g = (col >> 8) & 0xFF; + int b = (col) & 0xFF; + float coly = yuv_y(r, g, b); + float colu = yuv_u(r, g, b); + float colv = yuv_v(r, g, b); + float dist,dy,du,dv; + for (i = 0; i < 256; i++) { + if (palette[i] == col) { + lua_pushnumber(L, i); + return 1; + } + dy = coly - pal_yuv[i*3]; + du = colu - pal_yuv[i*3+1]; + dv = colv - pal_yuv[i*3+2]; + dist = dy*dy + du*du + dv*dv; + if (dist < ncv) { + nck = i; + ncv = dist; + } + } + lua_pushnumber(L, nck); + return 1; +} + +static int fb_copy(int x, int y, int w, int h, int x2, int y2) { + int i, j; + char* tmp = (char*) malloc(w*h*fb_bypp); + + for (j = 0; j < h; j++) { + char* ptr = &fb_ptr[XY_TO_FB((x), ((y) + (j)))]; + memcpy(&tmp[w*j*fb_bypp], ptr, w*fb_bypp); + } + for (j = 0; j < h; j++) { + char* ptr = &fb_ptr[XY_TO_FB((x2), (y2 + (j)))]; + memcpy(ptr, &tmp[w*j*fb_bypp], w*fb_bypp); + } + + free(tmp); +} + +static inline int fb_draw_16(int x, int y, ushort bg, ushort fg, int chr, int cwd) { + int table[4]; + int px, py; + int c = 0; + + if (fb_rot > 0) { + short* ptr = (short*) &fb_ptr; + for (py = 0; py < 16; py++) { + if (cwd == 2) { + c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; + } else if (cwd == 1) { + c = res_unifont[chr * 33 + 1 + py]; + } + for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { + *((short*) &fb_ptr[XY_TO_FB( + fb_xrot((x * 8) + px, (y * 16) + py), + fb_yrot((x * 8) + px, (y * 16) + py) + )]) = (c & 1) ? fg : bg; + c >>= 1; + } + } + } else { + table[0] = bg << 16 | bg; + table[1] = fg << 16 | bg; + table[2] = bg << 16 | fg; + table[3] = fg << 16 | fg; +/* for (py = 0; py < 16; py++) { + if (cwd == 2) { + c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; + } else if (cwd == 1) { + c = res_unifont[chr * 33 + 1 + py]; + } + ptr = (short*) (&fb_ptr[XY_TO_FB((x * 8), ((y * 16) + py))]); + for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { + ptr[px] = (c & 1) ? fg : bg; + c >>= 1; + } + } */ + int* ptr = (int*) (&fb_ptr[XY_TO_FB((x * 8), ((y * 16)))]); + for (py = 0; py < 16; py++) { + if (cwd == 2) { + c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; + ptr[7] = table[(c & 3)]; + c >>= 2; + ptr[6] = table[(c & 3)]; + c >>= 2; + ptr[5] = table[(c & 3)]; + c >>= 2; + ptr[4] = table[(c & 3)]; + c >>= 2; + ptr[3] = table[(c & 3)]; + c >>= 2; + ptr[2] = table[(c & 3)]; + c >>= 2; + ptr[1] = table[(c & 3)]; + c >>= 2; + ptr[0] = table[(c & 3)]; + c >>= 2; + } else if (cwd == 1) { + c = res_unifont[chr * 33 + 1 + py]; + ptr[3] = table[(c & 3)]; + c >>= 2; + ptr[2] = table[(c & 3)]; + c >>= 2; + ptr[1] = table[(c & 3)]; + c >>= 2; + ptr[0] = table[(c & 3)]; + c >>= 2; + } + ptr += fb_pitch >> 2; + } + } +} + +static inline int fb_draw_32(int x, int y, int bg, int fg, int chr, int cwd) { + int px, py; + int c = 0; + int* ptr; + if (fb_rot > 0) { + for (py = 0; py < 16; py++) { + if (cwd == 2) { + c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; + } else if (cwd == 1) { + c = res_unifont[chr * 33 + 1 + py]; + } + for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { + *((int*) &fb_ptr[XY_TO_FB( + fb_xrot((x * 8) + px, (y * 16) + py), + fb_yrot((x * 8) + px, (y * 16) + py) + )]) = (c & 1) ? fg : bg; + c >>= 1; + } + } + } else { + ptr = (int*) (&fb_ptr[XY_TO_FB((x * 8), ((y * 16) + py))]); + for (py = 0; py < 16; py++) { + if (cwd == 2) { + c = (res_unifont[chr * 33 + 2 + (py * 2)] << 8) | res_unifont[chr * 33 + 1 + (py * 2)]; + } else if (cwd == 1) { + c = res_unifont[chr * 33 + 1 + py]; + } + for (px = (cwd == 2 ? 15 : 7); px >= 0; px--) { + ptr[px] = (c & 1) ? fg : bg; + c >>= 1; + } + ptr += fb_pitch >> 2; + } + } +} + +static int fb_draw(int x, int y, int bg, int fg, int chr) { + if (x < 0 || x >= fb_cw || y < 0 || y >= fb_ch || bg < 0 || bg >= 256 || fg < 0 || fg >= 256 + || chr < 0 || chr >= 65536) { + return 0; + } + + colbuf[XY_TO_COLBUF(x, y, 0)] = (char) bg; + colbuf[XY_TO_COLBUF(x, y, 1)] = (char) fg; + chrbuf[XY_TO_CHRBUF(x, y)] = (ushort) chr; + + int cwd = res_unifont[chr * 33]; + if (cwd == 2 && x < (fb_cw - 1)) { + chrbuf[XY_TO_CHRBUF(x + 1, y)] = (ushort) 0; + } + if (fb_bpp == 32) { + fb_draw_32(x,y,palette[bg],palette[fg],chr,cwd); + } else if (fb_bpp == 16) { + fb_draw_16(x,y,(ushort) palette[bg],(ushort) palette[fg],chr,cwd); + } + return 0; +} + +static int l_fbput (lua_State *L) { + int x = lua_tonumber(L, 1); + int y = lua_tonumber(L, 2); + int bg = lua_tonumber(L, 3); + int fg = lua_tonumber(L, 4); + int chr = lua_tonumber(L, 5); + return fb_draw(x, y, bg, fg, chr); +} + +static int l_fbcopy (lua_State *L) { + int x = lua_tonumber(L, 1); + int y = lua_tonumber(L, 2); + int w = lua_tonumber(L, 3); + int h = lua_tonumber(L, 4); + int tx = x+lua_tonumber(L, 5); + int ty = y+lua_tonumber(L, 6); + int j, px = x<<3, py = y<<4, pw = w<<3, ph = h<<4, ptx = tx<<3, pty = ty<<4; + + char* tmpcol = (char*) malloc(w*h*2); + char* tmpchr = (char*) malloc(w*h*2); + + if (fb_rot == 1 || fb_rot == 3) { + j = pw; + pw = ph; + ph = j; + } + j = fb_xrot(px, py); + py = fb_yrot(px, py); + px = j; + j = fb_xrot(ptx, pty); + pty = fb_yrot(ptx, pty); + ptx = j; + + if (fb_rot == 1 || fb_rot == 2) { + px -= pw-1; + ptx -= pw-1; + } + if (fb_rot == 3 || fb_rot == 2) { + py -= ph-1; + pty -= ph-1; + } + + for (j = 0; j < h; j++) { + memcpy(&tmpcol[j*w*2], &colbuf[XY_TO_COLBUF(x, y+j, 0)], w * 2); + memcpy(&tmpchr[j*w*2], &chrbuf[XY_TO_CHRBUF(x, y+j)], w * 2); + } + + fb_copy(px, py, pw, ph, ptx, pty); + + for (j = 0; j < h; j++) { + memcpy(&colbuf[XY_TO_COLBUF(tx, ty+j, 0)], &tmpcol[j*w*2], w * 2); + memcpy(&chrbuf[XY_TO_CHRBUF(tx, ty+j)], &tmpchr[j*w*2], w * 2); + } + + free(tmpcol); + free(tmpchr); +} + +static int l_fbfill (lua_State *L) { + int x1 = lua_tonumber(L, 1); + int y1 = lua_tonumber(L, 2); + int x2 = lua_tonumber(L, 3); + int y2 = lua_tonumber(L, 4); + int bg = lua_tonumber(L, 5); + int fg = lua_tonumber(L, 6); + int chr = lua_tonumber(L, 7); + int i, j; + for (i = y1; i <= y2; i++) { + for (j = x1; j <= x2; j++) { + fb_draw(j, i, bg, fg, chr); + } + } + return 0; +} + +static int l_get_width (lua_State *L) { + lua_pushnumber(L, fb_cw); + return 1; +} + +static int l_get_height (lua_State *L) { + lua_pushnumber(L, fb_ch); + return 1; +} + +static int l_fb_ready (lua_State *L) { + lua_pushboolean(L, fb_ready); + return 1; +} + +static int l_fb_getbg (lua_State *L) { + int x = lua_tonumber(L, 1); + int y = lua_tonumber(L, 2); + if (x >= 0 && y >= 0 && x < fb_cw && y < fb_ch) { + lua_pushnumber(L, colbuf[XY_TO_COLBUF(x, y, 0)]); + } else { + lua_pushnumber(L, 0); + } + return 1; +} + +static int l_fb_getfg (lua_State *L) { + int x = lua_tonumber(L, 1); + int y = lua_tonumber(L, 2); + if (x >= 0 && y >= 0 && x < fb_cw && y < fb_ch) { + lua_pushnumber(L, colbuf[XY_TO_COLBUF(x, y, 1)]); + } else { + lua_pushnumber(L, 0); + } + return 1; +} + +static int l_fb_get (lua_State *L) { + int x = lua_tonumber(L, 1); + int y = lua_tonumber(L, 2); + if (x >= 0 && y >= 0 && x < fb_cw && y < fb_ch) { + lua_pushnumber(L, chrbuf[XY_TO_CHRBUF(x, y)]); + } else { + lua_pushnumber(L, 0); + } + return 1; +} + +void fb_start(lua_State *L) { + fb_file = open("/dev/fb0", O_RDWR); + if (fb_file == -1) { + printf("Error: cannot open framebuffer device"); + exit(1); + return; + } + + if (ioctl(fb_file, FBIOGET_FSCREENINFO, &fb_finfo) == -1) { + printf("Error reading fixed information"); + exit(1); + return; + } + + if (ioctl(fb_file, FBIOGET_VSCREENINFO, &fb_vinfo) == -1) { + printf("Error reading variable information"); + exit(1); + return; + } + + fb_vinfo.bits_per_pixel = 16; + if (fb_rot == 1 || fb_rot == 3) { + fb_cw = fb_vinfo.yres / 8; + fb_ch = fb_vinfo.xres / 16; + } else { + fb_cw = fb_vinfo.xres / 8; + fb_ch = fb_vinfo.yres / 16; + } + if (ioctl(fb_file, FBIOPUT_VSCREENINFO, &fb_vinfo) == -1) { + fb_vinfo.bits_per_pixel = 32; + if (ioctl(fb_file, FBIOPUT_VSCREENINFO, &fb_vinfo) == -1) { + printf("Error setting 32 or 16BPP mode"); + exit(1); + return; + } + } + + fb_bpp = fb_vinfo.bits_per_pixel; + fb_bypp = fb_bpp >> 3; + fb_pitch = fb_vinfo.xres_virtual * fb_bypp; + fb_xo = fb_vinfo.xoffset; + fb_yo = fb_vinfo.yoffset; + + fb_ptr = (char *)mmap(0, fb_vinfo.xres * fb_vinfo.yres * fb_bypp, PROT_READ | PROT_WRITE, MAP_SHARED, fb_file, 0); + if ((intptr_t)fb_ptr == -1) { + printf("Failed to map framebuffer device to memory"); + exit(1); + return; + } + + colbuf = (char *)malloc(2 * fb_cw * fb_ch); + chrbuf = (ushort *)malloc(2 * fb_cw * fb_ch); + + fb_ready = 1; + + struct luaL_Reg fblib[] = { + {"setPalette", l_set_palette}, + {"getWidth", l_get_width}, + {"getHeight", l_get_height}, + {"put", l_fbput}, + {"copy", l_fbcopy}, + {"fill", l_fbfill}, + {"isReady", l_fb_ready}, + {"getBackground", l_fb_getbg}, + {"getForeground", l_fb_getfg}, + {"get", l_fb_get}, + {"getNearest", l_get_nearest}, + {NULL, NULL} + }; + + luaL_openlib(L, "framebuffer", fblib, 0); +} diff --git a/src/c/modules.c b/src/c/modules.c index 82a64db..4175c12 100644 --- a/src/c/modules.c +++ b/src/c/modules.c @@ -20,6 +20,8 @@ void setup_modules(lua_State *L) { pushstuple(L, "internet", lua_internet); pushstuple(L, "sandbox", lua_sandbox); pushstuple(L, "textgpu", lua_textgpu); + pushstuple(L, "fbgpu", lua_fbgpu); + pushstuple(L, "color", lua_util_color); pushstuple(L, "random", lua_util_random); pushstuple(L, "buffer", lua_util_buffer); diff --git a/src/c/run.c b/src/c/run.c index bc45cef..9bafafe 100644 --- a/src/c/run.c +++ b/src/c/run.c @@ -28,6 +28,7 @@ void run_init() { setup_modules (L); luanative_start (L); internet_start (L); + fb_start (L); termutils_start (L); epoll_prepare(); diff --git a/src/lua/core/component.lua b/src/lua/core/component.lua index ae16845..e409479 100644 --- a/src/lua/core/component.lua +++ b/src/lua/core/component.lua @@ -59,6 +59,11 @@ function api.register(address, ctype, proxy, doc) end end modules.computer.api.pushSignal("component_added", address, ctype) + if native.debug then + local caller = debug.getinfo(2) + local msg = caller.short_src .. ":".. caller.currentline .. " > component.register(" .. address .. ", " .. ctype .. ")" + native.log(msg) + end return address end @@ -104,6 +109,7 @@ function api.invoke(address, method, ...) local msg = tostring((native.uptime() - start) / 1000) .. " [+" .. native.uptime() - last .. "] " .. caller.short_src .. ":".. caller.currentline .. " > c.invoke(" .. address .. "): " .. components[address].type .. "." .. method .. "(" .. table.concat(t, ", ") .. ")" + native.log(msg) end return components[address].rawproxy[method](...) end diff --git a/src/lua/core/fbgpu.lua b/src/lua/core/fbgpu.lua new file mode 100644 index 0000000..b95137a --- /dev/null +++ b/src/lua/core/fbgpu.lua @@ -0,0 +1,171 @@ +local fbgpu = {} + +local mapping = {} + +for i=0,15 do + mapping[i] = (i * 15) << 16 | (i * 15) << 8 | (i * 15) +end + +for i=0,239 do + local b = math.floor((i % 5) * 255 / 4.0) + local g = math.floor((math.floor(i / 5.0) % 8) * 255 / 7.0) + local r = math.floor((math.floor(i / 40.0) % 6) * 255 / 5.0) + mapping[16+i] = r << 16 | g << 8 | b +end + +--[[local nw = io.write +io.write = function(...) + nw(...) + io.flush() + native.sleep(20000) +end]]-- + +local fb = framebuffer +local write = io.write +local flush = io.flush + +for k,v in pairs(mapping) do + fb.setPalette(k, v) +end + +local background = 0 +local foreground = 0 + +local usub + +function fbgpu.start() + usub = modules.sandbox.unicode.sub + 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 and color >= 0 and color < 256 then + background = color + return mapping[color] + end + local old = background + background = fb.getNearest(color) + return mapping[old] + end + function gpu.setForeground(color, isPaletteIndex) + checkArg(1, color, "number") + checkArg(2, isPaletteIndex, "boolean", "nil") + if isPaletteIndex and color >= 0 and color < 256 then + foreground = color + return mapping[color] + end + local old = foreground + foreground = fb.getNearest(color) + 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(index, value) + checkArg(1, index, "number") + checkArg(2, value, "number") + fb.setPalette(index, value) + return value + end + function gpu.maxDepth() + return 8 + end + function gpu.setDepth() + return false + end + function gpu.getDepth() + return 8 + end + function gpu.maxResolution() + return fb.getWidth(), fb.getHeight() + end + function gpu.getResolution() + return fb.getWidth(), fb.getHeight() + 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 utf8.char(fb.get(x-1, y-1)) + 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 + local i = 0 + value:gsub(".", function(c) + fb.put(x+i-1, y-1, background, foreground, utf8.codepoint(c)) + i = i+1 + end) + else + local i = 0 + value:gsub(".", function(c) + fb.put(x-1, y+i-1, background, foreground, utf8.codepoint(c)) + i = i+1 + 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") + fb.copy(x-1, y-1, w, h, tx, ty); + 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 = ch:sub(1, 1) + fb.fill(x-1, y-1, x+w-2, y+h-2, background, foreground, utf8.codepoint(ch)) + return true + end + + local w, h = gpu.getResolution() + gpu.setForeground(0xFFFFFF) + gpu.setBackground(0x000000) + + termutils.init() + write("\x1b[?25l") --Disable cursor + + modules.component.api.register(nil, "gpu", gpu) + 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") --Enable cursor on quit + end +end + +return fbgpu diff --git a/src/lua/core/init.lua b/src/lua/core/init.lua index caba669..37e8204 100644 --- a/src/lua/core/init.lua +++ b/src/lua/core/init.lua @@ -62,7 +62,12 @@ function main() --Components loadModule("eeprom") loadModule("gpio") - loadModule("textgpu") + + if framebuffer.isReady() then + loadModule("fbgpu") + else + loadModule("textgpu") + end loadModule("filesystem") loadModule("internet") @@ -83,7 +88,12 @@ function main() modules.filesystem.register("/", "11111111-1111-1111-1111-111111111111") end modules.computer.tmp = modules.filesystem.register("/tmp/lupi-" .. modules.random.uuid()) - modules.textgpu.start() + + if framebuffer.isReady() then + modules.fbgpu.start() + else + modules.textgpu.start() + end if native.debug then modules.debug.hook() @@ -106,9 +116,10 @@ for k, hook in ipairs(deadhooks) do lprint(cause) end end + lprint("Hooks executed: " .. #deadhooks) if not state then lprint("LuPI finished with following error:") lprint(tb) -end \ No newline at end of file +end diff --git a/src/lua/core/util/color.lua b/src/lua/core/util/color.lua index dc9f582..617a9c6 100644 --- a/src/lua/core/util/color.lua +++ b/src/lua/core/util/color.lua @@ -1,5 +1,9 @@ local color = {} +function color.rgbToYuv(r, g, b) + return (r * 0.299 + g * 0.587 + b * 0.114), (r * (-0.147) + g * (-0.289) + b * 0.436), (r * 0.615 + g * (-0.515) + b * (-0.1)) +end + function color.rgbToHsv(r, g, b) local h, s, v local min, max, delta @@ -53,9 +57,12 @@ 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) + local th, ts, tv = color.rgbToYuv((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) + if col == to then + return k + end + local h, s, v = color.rgbToYuv((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 @@ -65,4 +72,4 @@ function color.nearest(to, colors) return lowestk end -return color \ No newline at end of file +return color