From 575b140a57e2bb86f05b8d18f01a9f2cea1f5034 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Fri, 21 Apr 2017 18:53:18 +0200 Subject: more glitch art :) --- src/lib/include/kogata/draw.h | 3 +- src/lib/libkogata/draw.c | 20 +++-- src/sysapp/login/main.lua | 26 +++++- src/sysbin/lx/lxdrawlib.c | 178 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 207 insertions(+), 20 deletions(-) diff --git a/src/lib/include/kogata/draw.h b/src/lib/include/kogata/draw.h index d00036f..d8a2e13 100644 --- a/src/lib/include/kogata/draw.h +++ b/src/lib/include/kogata/draw.h @@ -57,7 +57,8 @@ void g_scroll_up(fb_t *fb, int l); // ---- Text manipulation font_t *g_load_font(const char* fontname); -void g_free_font(font_t *f); +void g_incref_font(font_t *f); +void g_decref_font(font_t *f); int g_text_width(font_t *f, const char* text); int g_text_height(font_t *f, const char* text); diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c index d9a4268..29cae31 100644 --- a/src/lib/libkogata/draw.c +++ b/src/lib/libkogata/draw.c @@ -244,6 +244,7 @@ typedef struct font { uint32_t nchars; } ascii_bitmap; }; + int nrefs; } font_t; font_t *g_load_ascii_bitmap_font(fd_t f) { @@ -272,6 +273,8 @@ font_t *g_load_ascii_bitmap_font(fd_t f) { size_t rd = sc_read(f, sizeof(h), h.ch * h.nchars, (char*)font->ascii_bitmap.data); if (rd != h.ch * h.nchars) goto error; + font->nrefs = 1; + return font; error: @@ -291,12 +294,19 @@ font_t *g_load_font(const char* fontname) { return 0; } -void g_free_font(font_t *f) { - if (f->type == FONT_ASCII_BITMAP) { - free(f->ascii_bitmap.data); - } +void g_incref_font(font_t *f) { + f->nrefs++; +} - free(f); +void g_decref_font(font_t *f) { + f->nrefs--; + + if (f->nrefs == 0) { + if (f->type == FONT_ASCII_BITMAP) { + free(f->ascii_bitmap.data); + } + free(f); + } } int g_text_width(font_t *font, const char* text) { diff --git a/src/sysapp/login/main.lua b/src/sysapp/login/main.lua index 50ecd20..0c54769 100644 --- a/src/sysapp/login/main.lua +++ b/src/sysapp/login/main.lua @@ -18,15 +18,35 @@ for x = 0, 255 do end end +local fnt = draw.load_font('default') + local i = 1 while true do - surface:plot(i % (vesa_info.width-3), - i % (vesa_info.height-1), + surface:rect((i*3) % (vesa_info.width-3), + (i*3) % (vesa_info.height-5), + 3, 3, surface:rgb(i % 256, (i + 96) % 256, (i + 2*96) % 256)) i = i + 1 - if i % 100000 == 0 then print(i) end + if i % 10000 == 0 then + local x0 = math.random(vesa_info.width)-1 + local x1 = math.random(vesa_info.width)-1 + local y0 = math.random(vesa_info.height)-1 + local y1 = math.random(vesa_info.height)-1 + if x0 > x1 then x0, x1 = x1, x0 end + if y0 > y1 then y0, y1 = y1, y0 end + local c = surface:rgb(math.random(0, 255), math.random(0, 255), math.random(0, 255)) + surface:fillrect(x0, y0, x1-x0, y1-y0, c) + end + if i % 10000 == 0 then + print(i) + local txt = tostring(i) + surface:fillrect(0, 0, fnt:text_width(txt), + fnt:text_height(txt), + surface:rgb(0, 0, 0)) + surface:write(0, 0, txt, fnt, surface:rgb(255, 0, 0)) + end end os.exit() diff --git a/src/sysbin/lx/lxdrawlib.c b/src/sysbin/lx/lxdrawlib.c index 71c9819..91bf07f 100644 --- a/src/sysbin/lx/lxdrawlib.c +++ b/src/sysbin/lx/lxdrawlib.c @@ -1,5 +1,5 @@ /* -** Lua eXtended ioctl library +** Lua eXtended draw library */ #define lxdrawlib_c @@ -24,6 +24,12 @@ #include "lxlib.h" +typedef struct { + font_t *font; +} drawlib_font; + +#define FONT "lx.draw.font" + typedef struct { fb_t *fb; fb_region_t subregion; @@ -32,6 +38,57 @@ typedef struct { #define SURFACE "lx.draw.surface" +// ==================================================================== +// FONTS + +static int draw_loadfont(lua_State *L) { + const char* name = luaL_checkstring(L, 1); + font_t *f = g_load_font(name); + if (f == NULL) { + lua_pushnil(L); + return 1; + } + + drawlib_font *ff = (drawlib_font*)lua_newuserdata(L, sizeof(drawlib_font)); + luaL_getmetatable(L, FONT); + lua_setmetatable(L, -2); + + ff->font = f; + + return 1; +} + +static int font_gc(lua_State *L) { + drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 1, FONT); + + if(f->font == NULL) { + luaL_error(L, "f->font == NULL ?"); + } + g_decref_font(f->font); + f->font = NULL; + + return 0; +} + +static int font_text_width(lua_State *L) { + drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 1, FONT); + const char* txt = luaL_checkstring(L, 2); + + lua_pushinteger(L, g_text_width(f->font, txt)); + return 1; +} + +static int font_text_height(lua_State *L) { + drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 1, FONT); + const char* txt = luaL_checkstring(L, 2); + + lua_pushinteger(L, g_text_height(f->font, txt)); + return 1; +} + +// ==================================================================== +// SURFACES + static int draw_from_fd(lua_State *L) { int fd = luaL_checkinteger(L, 1); luaL_checktype(L, 2, LUA_TTABLE); @@ -43,20 +100,22 @@ static int draw_from_fd(lua_State *L) { geom.pitch = getintfield(L, 2, "pitch"); geom.memory_model = getintfield(L, 2, "memory_model"); + fb_t *fb = g_fb_from_file(fd, &geom); + if (fb == NULL) { + lua_pushnil(L); + return 1; + } + drawlib_surface *s = (drawlib_surface*)lua_newuserdata(L, sizeof(drawlib_surface)); luaL_getmetatable(L, SURFACE); lua_setmetatable(L, -2); - s->fb = g_fb_from_file(fd, &geom); - if (s->fb == NULL) { - lua_pop(L, 1); - lua_pushnil(L); - } else { - s->subregion.x = s->subregion.y = 0; - s->subregion.w = geom.width; - s->subregion.h = geom.height; - s->has_subregion = false; - } + s->fb = fb; + s->subregion.x = s->subregion.y = 0; + s->subregion.w = geom.width; + s->subregion.h = geom.height; + s->has_subregion = false; + return 1; } @@ -124,14 +183,92 @@ static int surface_plot(lua_State *L) { int y = luaL_checkinteger(L, 3); color_t c = (color_t)lx_checklightudata(L, 4); + // TODO: relative to subregion! g_plot(s->fb, x, y, c); return 0; } +static int surface_hline(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + int w = luaL_checkinteger(L, 4); + color_t c = (color_t)lx_checklightudata(L, 5); + + // TODO: relative to subregion! + g_hline(s->fb, x, y, w, c); + return 0; +} + +static int surface_vline(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + int h = luaL_checkinteger(L, 4); + color_t c = (color_t)lx_checklightudata(L, 5); + + // TODO: relative to subregion! + g_vline(s->fb, x, y, h, c); + return 0; +} + +static int surface_line(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + int x2 = luaL_checkinteger(L, 4); + int y2 = luaL_checkinteger(L, 5); + color_t c = (color_t)lx_checklightudata(L, 6); + + // TODO: relative to subregion! + g_line(s->fb, x, y, x2, y2, c); + return 0; +} + +static int surface_rect(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + int w = luaL_checkinteger(L, 4); + int h = luaL_checkinteger(L, 5); + color_t c = (color_t)lx_checklightudata(L, 6); + + // TODO: relative to subregion! + g_rect(s->fb, x, y, w, h, c); + return 0; +} + +static int surface_fillrect(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + int w = luaL_checkinteger(L, 4); + int h = luaL_checkinteger(L, 5); + color_t c = (color_t)lx_checklightudata(L, 6); + + // TODO: relative to subregion! + g_fillrect(s->fb, x, y, w, h, c); + return 0; +} + +static int surface_write(lua_State *L) { + drawlib_surface *s = (drawlib_surface*)luaL_checkudata(L, 1, SURFACE); + int x = luaL_checkinteger(L, 2); + int y = luaL_checkinteger(L, 3); + const char *text = luaL_checkstring(L, 4); + drawlib_font *f = (drawlib_font*)luaL_checkudata(L, 5, FONT); + color_t c = (color_t)lx_checklightudata(L, 6); + + // TODO: relative to subregion! + g_write(s->fb, x, y, text, f->font, c); + return 0; +} + /* }====================================================== */ static const luaL_Reg drawlib[] = { {"from_fd", draw_from_fd}, + {"load_font", draw_loadfont}, {NULL, NULL} }; @@ -139,10 +276,23 @@ static const luaL_Reg surface_meta[] = { {"sub", surface_sub}, {"rgb", surface_rgb}, {"plot", surface_plot}, + {"hline", surface_hline}, + {"vline", surface_vline}, + {"line", surface_line}, + {"rect", surface_rect}, + {"fillrect", surface_fillrect}, + {"write", surface_write}, {"__gc", surface_gc}, {NULL, NULL} }; +static const luaL_Reg font_meta[] = { + {"text_width", font_text_width}, + {"text_height", font_text_height}, + {"__gc", font_gc}, + {NULL, NULL} +}; + LUAMOD_API int lx_open_draw (lua_State *L) { luaL_newlib(L, drawlib); @@ -153,6 +303,12 @@ LUAMOD_API int lx_open_draw (lua_State *L) { lua_setfield(L, -2, "__index"); lua_pop(L, 1); + luaL_newmetatable(L, FONT); + luaL_setfuncs(L, font_meta, 0); + lua_pushvalue(L, -1); + lua_setfield(L, -2, "__index"); + lua_pop(L, 1); + return 1; } -- cgit v1.2.3