diff --git a/kistaro_compositor.p8 b/kistaro_compositor.p8 index e251e46..0256857 100644 --- a/kistaro_compositor.p8 +++ b/kistaro_compositor.p8 @@ -67,18 +67,22 @@ function _draw() mode:draw() end --- for each object in t, invoke --- t:mname(), converting mname --- from string to method name. --- if there is no method by that --- name, quietly skip it. -function subeach_opt(t, mname) +-- if t[mname] is a thing, +-- invoke it as a method. else, +-- try each object in t +function outer_or_each_opt(t, mname) + local fun = t[mname] + if fun then + fun(t) + return + end foreach(t, function(o) local f = o[mname] if(f) f(o) end) end + -- generate standard "overlay" -- constructor for type tt. -- if more is defined, generated @@ -105,6 +109,117 @@ function mknew(tt, more) end end +-->8 +-- window manager + +------------------------------- +-- view +------------------------------- +-- composits drawable items. +-- add items to .views to +-- composit them. x and y are +-- relative reverse camera +-- offsets. drawable items will +-- observe appropriate incoming +-- camera and clip state. +-- clipping respects existing +-- clipping so stacked views +-- intersect. +------------------------------- +view = { + x=0, + y=0, + w=128, + h=128, +} +mknew(view, function(x) + if (not x.views) x.views = {} +end) + +function view.of(subviews) + return view.new{views=subviews} +end + +function view:update() + outer_or_each_opt(self.views, "update") +end + +function view:draw() + local oldcam, oldclip = $0x5f28, $0x5f20 + poke2(0x5f28, %0x5f28-self.x) + poke2(0x5f2a, %0x5f2a-self.y) + clip(-%0x5f28, -%0x5f2a, self.w, self.h, true) + outer_or_each_opt(self.views, "draw") + poke4(0x5f20, oldclip) + poke4(0x5f28, oldcam) +end + +-- draws opaque rectangles. +-- default bg is equivalent to +-- clip-aware cls. +-- restores prior fill palette. +bg = { + x=0,y=0,w=128,h=128,fp=0,c=0 +} +mknew(bg) + +function bg:draw() + local oldfp=fillp(self.fp) + rectfill(self.x,self.y,self.x+self.w,self.y+self.h,self.c) + fillp(oldfp) +end + +------------------------------- +-- animator +------------------------------- +-- animator is a drawable item +-- that manages a linked list of +-- temporary drawables. a +-- temporary drawable is dropped +-- when its :update returns +-- a non-false value. +------------------------------- +animator = {} +mknew(animator) + +function animator:update() + local p,n=self, self.next + while n do + if n.item:update() then + local nn = n.next + if (not nn) self.tail = p + p.next = n.next + else + p = n + end + n = p.next + end +end + +function animator:draw() + local n = self.next + while n do + n.item:draw() + n = n.next + end +end + +-- add a new drawable under all +-- existing other items. +-- (it draws first) +function animator:push_under(i) + self.next={next=self.next, item=i} +end + +-- add a new drawable over all +-- existing other items. +-- (it draws last) +function animator:push_over(i) + local target, node = self.tail or self, {item=i} + target.next=node + self.tail=node +end + -->8 -- title -- (currently a placeholder) @@ -191,120 +306,6 @@ function title:draw() print("panel extreme", 1, 1, self.fcol) end --->8 --- window manager - -------------------------------- --- view -------------------------------- --- composits drawable items. --- add items to .views to --- composit them. x and y are --- relative reverse camera --- offsets. drawable items will --- observe appropriate incoming --- camera and clip state. --- clipping respects existing --- clipping so stacked views --- intersect. -------------------------------- -view = { - x=0, - y=0, - w=128, - h=128, -} -mknew(view, function(x) - if (not x.views) x.views = {} -end) - -function view.of(subviews) - return view.new{views=subviews} -end - -function view:update() - subeach_opt(self.views, "update") -end - -function view:draw() - local oldcam, oldclip = $0x5f28, $0x5f20 - poke2(0x5f28, %0x5f28-self.x) - poke2(0x5f2a, %0x5f2a-self.y) - clip(-%0x5f28, -%0x5f2a, self.w, self.h, true) - subeach_opt(self.views, "draw") - poke4(0x5f20, oldclip) - poke4(0x5f28, oldcam) -end - --- draws opaque rectangles. --- default bg is equivalent to --- clip-aware cls. --- restores prior fill palette. -bg = { - x=0,y=0,w=128,h=128,fp=0,c=0 -} -mknew(bg) - -function bg:draw() - local oldfp=fillp(self.fp) - rectfill(self.x,self.y,self.x+self.w,self.y+self.h,self.c) - fillp(oldfp) -end - -------------------------------- --- animator -------------------------------- --- animator is a drawable item --- that manages a linked list of --- temporary drawables. a --- temporary drawable is dropped --- when its :update returns --- a non-false value. -------------------------------- -animator = {} -mknew(animator) - -function animator:update() - local p,n=self, self.next - while n do - if n.item:update() then - local nn = n.next - if (not nn) self.tail = p - p.next = n.next - else - p = n - end - n = p.next - end -end - -function animator:draw() - local n = self.next - while n do - n.item:draw() - n = n.next - end -end - --- add a new drawable under all --- existing other items. --- (it draws first) -function animator:push_under(i) - self.next={next=self.next, item=i} -end - --- add a new drawable over all --- existing other items. --- (it draws last) -function animator:push_over(i) - local target, node = self.tail or self, {item=i} - target.next=node - self.tail=node -end - - --->8 --- board __gfx__ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000