aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2017-05-04 17:20:00 +0200
committerAlex Auvolat <alex@adnab.me>2017-05-04 17:20:00 +0200
commit45f9f92f51dda29d9181e27eec0261ec3127fda4 (patch)
tree2df755b19115113eb9a2e8f139b3c23d6f540f41
parentc7486a2113171d4d3fe7891ddf898f9f00865cc9 (diff)
downloadkogata-45f9f92f51dda29d9181e27eec0261ec3127fda4.tar.gz
kogata-45f9f92f51dda29d9181e27eec0261ec3127fda4.zip
Stuff works but we need to fix region_alloc.c
-rw-r--r--src/lib/libc/debug.c2
-rw-r--r--src/lib/libkogata/draw.c4
-rw-r--r--src/syslua/lx/tk.lua157
3 files changed, 126 insertions, 37 deletions
diff --git a/src/lib/libc/debug.c b/src/lib/libc/debug.c
index d88b204..29820ac 100644
--- a/src/lib/libc/debug.c
+++ b/src/lib/libc/debug.c
@@ -8,12 +8,14 @@
void sys_panic(const char* msg, const char* file, int line) {
dbg_printf("PANIC in user process\n %s\n at %s:%d\n", msg, file, line);
+ *((uint32_t*)NULL) = 1; //provoke segfault
exit(-1);
while(true);
}
void sys_panic_assert(const char* assert, const char* file, int line) {
dbg_printf("ASSERT FAILED in user process\n %s\n at %s:%d\n", assert, file, line);
+ *((uint32_t*)NULL) = 1; //provoke segfault
exit(-1);
while(true);
}
diff --git a/src/lib/libkogata/draw.c b/src/lib/libkogata/draw.c
index 9ef4031..1b4f225 100644
--- a/src/lib/libkogata/draw.c
+++ b/src/lib/libkogata/draw.c
@@ -633,8 +633,6 @@ void g_region_write(fb_t *fb, fb_region_t *reg, int x, int y, const char* text,
float scale = stbtt_ScaleForPixelHeight(&font->stbtt.info, size);
float xpos = 1;
- dbg_printf("Write TTF %s %d\n", text, size);
-
uint8_t *tmp = (uint8_t*)malloc(size*size*2);
size_t tmp_size = size*size*2;
if (tmp == NULL) return;
@@ -650,8 +648,6 @@ void g_region_write(fb_t *fb, fb_region_t *reg, int x, int y, const char* text,
stbtt_GetCodepointBitmapBoxSubpixel(&font->stbtt.info, codepoint, scale, scale, x_shift, 0, &x0, &y0, &x1, &y1);
int w = x1 - x0, h = y1 - y0;
- dbg_printf("%d %d %d %d\n", x0, y0, x1, y1);
-
if (tmp_size < (size_t)w*h) {
free(tmp);
tmp_size = 2*w*h;
diff --git a/src/syslua/lx/tk.lua b/src/syslua/lx/tk.lua
index 374e260..0862e5b 100644
--- a/src/syslua/lx/tk.lua
+++ b/src/syslua/lx/tk.lua
@@ -3,6 +3,70 @@ local sys = require 'lx.sys'
local tk = {}
+-- UTIL
+
+function region_operation(reg1, reg2, sel_fun)
+ local xs = {reg1.x, reg1.x + reg1.w, reg2.x, reg2.x + reg2.w}
+ local ys = {reg1.y, reg1.y + reg1.h, reg2.y, reg2.y + reg2.h}
+ table.sort(xs)
+ table.sort(ys)
+ local pieces = {}
+ local function add_region(x, y, w, h)
+ for i, r in pairs(pieces) do
+ if r.y == y and r.h == h and r.x + r.w == x then
+ table.remove(pieces, i)
+ add_region(r.x, r.y, r.w + w, r.h)
+ return
+ elseif r.x == x and r.w == w and r.y + r.h == y then
+ table.remove(pieces, i)
+ add_region(r.x, r.y, r.w, r.h + h)
+ return
+ end
+ end
+ table.insert(pieces, {x = x, y = y, w = w, h = h})
+ end
+ for i = 1, 3 do
+ for j = 1, 3 do
+ local x0, x1, y0, y1 = xs[i], xs[i+1], ys[j], ys[j+1]
+ if x1 > x0 and y1 > y0 then
+ if sel_fun(x0, x1, y0, y1) then
+ add_region(x0, y0, x1 - x0, y1 - y0)
+ end
+ end
+ end
+ end
+ return pieces
+end
+
+function region_diff(reg1, reg2)
+ return region_operation(reg1, reg2,
+ function(x0, x1, y0, y1)
+ return (x0 >= reg1.x and x0 < reg1.x + reg1.w and y0 >= reg1.y and y0 < reg1.y + reg1.h)
+ and not (x0 >= reg2.x and x0 < reg2.x + reg2.w and y0 >= reg2.y and y0 < reg2.y + reg2.h)
+ end
+ )
+end
+
+function region_inter(reg1, reg2)
+ return region_operation(reg1, reg2,
+ function(x0, x1, y0, y1)
+ return (x0 >= reg1.x and x0 < reg1.x + reg1.w and y0 >= reg1.y and y0 < reg1.y + reg1.h)
+ and (x0 >= reg2.x and x0 < reg2.x + reg2.w and y0 >= reg2.y and y0 < reg2.y + reg2.h)
+ end
+ )
+end
+
+function region_union(reg1, reg2)
+ return region_operation(reg1, reg2,
+ function(x0, x1, y0, y1)
+ return (x0 >= reg1.x and x0 < reg1.x + reg1.w and y0 >= reg1.y and y0 < reg1.y + reg1.h)
+ or (x0 >= reg2.x and x0 < reg2.x + reg2.w and y0 >= reg2.y and y0 < reg2.y + reg2.h)
+ end
+ )
+end
+
+
+
function tk.widget(width, height)
local w = {
width = width,
@@ -23,6 +87,15 @@ function tk.widget(width, height)
-- Replaced by widget code by a function that does the actual drawing
end
+ function w:redraw_sub(x0, y0, buf, subwidget)
+ local region = {x = x0, y = y0, w = buf:width(), h = buf:height()}
+ local subregion = {x = subwidget.x, y = subwidget.y, w = subwidget.width, h = subwidget.height}
+ local inter = region_inter(region, subregion)
+ for _, z in pairs(inter) do
+ subwidget:redraw(z.x - subwidget.x, z.y - subwidget.y, buf:sub(z.x - x0, z.y - y0, z.w, z.h))
+ end
+ end
+
function w:on_mouse_down(x, y, lb, rb, mb)
-- Handler for mouse down event
end
@@ -127,14 +200,7 @@ function tk.wm_widget()
end
function win:redraw(x0, y0, buf)
- local xx0 = math.max(x0, 1)
- local yy0 = math.max(y0, 21)
-
- local ww, hh = buf:width() - (xx0-x0), buf:height() - (yy0-y0)
- if xx0-1 + ww > content.width then ww = content.width - xx0+1 end
- if yy0-21 + ww > content.height then hh = content.height - yy0+21 end
-
- self.content:redraw(xx0-1, yy0-21, buf:sub(xx0-x0, yy0-y0, ww, hh))
+ self:redraw_sub(x0, y0, buf, self.content)
buf:rect(-x0, -y0, self.width, self.height, buf:rgb(255, 128, 0))
buf:fillrect(-x0+1, -y0+1, win.width-2, 20, buf:rgb(200, 200, 200))
@@ -161,12 +227,15 @@ function tk.wm_widget()
function win:on_mouse_move(px, py, nx, ny)
if self.moving then
- self.visible = false
- wm:redraw_win(self)
+ local reg1 = {x = self.x, y = self.y, w = self.width, h = self.height}
self.x = self.x + nx - px
self.y = self.y + ny - py
- self.visible = true
- wm:redraw_win(self)
+ local reg2 = {x = self.x, y = self.y, w = self.width, h = self.height}
+ local pieces = region_diff(reg1, reg2)
+ table.insert(pieces, reg2)
+ for _, p in pairs(pieces) do
+ wm:redraw_region(p.x, p.y, p.w, p.h)
+ end
else
self.content:on_mouse_move(px-1, py-21, px-1, py-21)
end
@@ -191,39 +260,61 @@ function tk.wm_widget()
end
end
+ function wm:redraw_region(x, y, w, h)
+ local ok = region_inter({x = 0, y = 0, w = self.width, h = self.height},
+ {x = x, y = y, w = w, h = h})
+ for _, r in pairs(ok) do
+ self:redraw(r.x, r.y, self:get_draw_buffer(r.x, r.y, r.w, r.h))
+ end
+ end
+
function wm:redraw_win(win)
- local x0, y0 = math.max(0, win.x), math.max(0, win.y)
- local width = win.x + win.width - x0
- local height = win.y + win.height - y0
- self:redraw(x0, y0, self:get_draw_buffer(x0, y0, width, height))
+ self:redraw_region(win.x, win.y, win.width, win.height)
end
function wm:redraw(x0, y0, buf)
- -- Draw background
-
- local step = 32
- local halfstep = 16
- for x = x0 - (x0 % step), x0 + buf:width(), step do
- for y = y0 - (y0 % step), y0 + buf:height(), step do
- buf:fillrect(x - x0, y - y0, halfstep, halfstep, buf:rgb(110, 110, 140))
- buf:fillrect(x - x0 + halfstep, y - y0 + halfstep, halfstep, halfstep, buf:rgb(110, 110, 140))
- buf:fillrect(x - x0 + halfstep, y - y0, halfstep, halfstep, buf:rgb(110, 140, 110))
- buf:fillrect(x - x0, y - y0 + halfstep, halfstep, halfstep, buf:rgb(110, 140, 110))
- end
- end
+ local remaining = { {x = x0, y = y0, w = buf:width(), h = buf:height()} }
-- TODO do this in inverse order and clip regions of hidden windows
-- so that less redrawing is done
- for i = 1, #self.windows do
+ for i = #self.windows, 1, -1 do
win = self.windows[i]
if win.visible then
- local wx0, wy0 = math.max(x0, win.x), math.max(y0, win.y)
- local ww, wh = win.x + win.width - wx0, win.y + win.height - wy0
- if ww > 0 and wh > 0 then
- win:redraw(wx0 - win.x, wy0 - win.y, buf:sub(wx0 - x0, wy0 - y0, ww, wh))
+ local remaining2 = {}
+ local win_reg = {x = win.x, y = win.y, w = win.width, h = win.height}
+
+ for _, reg in pairs(remaining) do
+ local draw_to = region_inter(reg, win_reg)
+ for _, reg2 in pairs(draw_to) do
+ win:redraw(reg2.x - win.x, reg2.y - win.y, buf:sub(reg2.x - x0, reg2.y - y0, reg2.w, reg2.h))
+ end
+
+ local remain_to = region_diff(reg, win_reg)
+ for _, reg2 in pairs(remain_to) do
+ table.insert(remaining2, reg2)
+ end
+ end
+
+ remaining = remaining2
+ end
+ end
+
+ -- Draw background
+ function draw_background(x0, y0, buf)
+ local step = 32
+ local halfstep = 16
+ for x = x0 - (x0 % step), x0 + buf:width(), step do
+ for y = y0 - (y0 % step), y0 + buf:height(), step do
+ buf:fillrect(x - x0, y - y0, halfstep, halfstep, buf:rgb(110, 110, 140))
+ buf:fillrect(x - x0 + halfstep, y - y0 + halfstep, halfstep, halfstep, buf:rgb(110, 110, 140))
+ buf:fillrect(x - x0 + halfstep, y - y0, halfstep, halfstep, buf:rgb(110, 140, 110))
+ buf:fillrect(x - x0, y - y0 + halfstep, halfstep, halfstep, buf:rgb(110, 140, 110))
end
end
end
+ for _, reg in pairs(remaining) do
+ draw_background(reg.x, reg.y, buf:sub(reg.x - x0, reg.y - y0, reg.w, reg.h))
+ end
end
function wm:find_win(x, y)