pico-8 cartridge // http://www.pico-8.com version 41 __lua__ -- panel extreme -- by kistaro windrider ------------------------------- -- bsd 0-clause license ------------------------------- -- copyright 2023 kistaro windrider -- -- permission to use, copy, -- modify, and/or distribute -- this software for any -- purpose with or without fee -- is hereby granted. -- -- the software is provided -- "as is" and the author -- disclaims all warranties -- with regard to this software -- including all implied -- warranties of merchantability -- and fitness. in no event -- shall the author be liable -- for any special, direct, -- indirect, or consequential -- damages or any damages -- whatsoever resulting from -- loss of use, data or profits, -- whether in an action of -- contract, negligence or -- other tortious action, -- arising out of or in -- connection with the use or -- performance of this software. ------------------------------- -- major, release, revision -- change major version to break -- save compatibility version={0,0,1} ------------------------------- -- globals ------------------------------- -- mode: table -- {:update(), :draw()}. -- receives frame callbacks. -- version: [3]int constant. -- major, minor, release. -- change major version to -- break save compatibility. -- constant. ------------------------------- function _init() cartdata("panel_extreme"..version[1]) mode = init_title() end function _update60() mode:update() end function _draw() mode:draw() end -- 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 -- new calls more(ret) after -- ret is definitely not nil -- before calling setmetatable. -- use to initialize mutables. function mknew(tt, more) local mt = {__index=tt} -- check "more" only once ever if more then tt.new = function(ret) if (not ret) ret = {} more(ret) setmetatable(ret, mt) return ret end else tt.new=function(ret) if (not ret) ret = {} setmetatable(ret, mt) return ret end 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) title = {fidx=1} mknew(title) function init_title() g_animator = animator.new() return view.of{ bg.new(), {update=boomer}, g_animator, titleframe(), titleframe(), titleframe(), titleframe(), titleframe(), } end boom = {} mknew(boom) function boom:update() self.r += 1 return self.r > 128 end function boom:draw() circ(self.x, self.y, self.r, rnd(4)\1+7) end function boomer(self) if rnd() < 0.1 then g_animator:push_over( boom.new{ x=rnd(128), y=rnd(128), r=0 }) end end function titleframe() local tx = title.new{fidx=rnd(#titleglow)\1+1} local v = view.new{ x=rnd(63), y=rnd(121), w=53, h=7, views={bg.new{c=rnd(64)\1,fp=rnd(32768)*2\1},tx} } v.update = function(self) self.x += rnd() - 0.5 self.y += rnd() - 0.5 local b = btn() if (b & 0x1 > 0) self.x -= 0.25 if (b & 0x2 > 0) self.x += 0.25 if (b & 0x4 > 0) self.y -= 0.25 if (b & 0x8 > 0) self.y += 0.25 if b & 0x10 > 0 then self.x -= (self.x-42.5)/10 self.y -= (self.y-60.5)/10 end if b & 0x20 > 0 then self.x += (self.x-42.5)/10 self.y += (self.y-60.5)/10 end view.update(v) end return v end -- obnoxious flicker effect titleglow = split"5,6,7,7,7,7,6,5,1,2,8,9,10,7,10,9,4,5,3,3,11,11,7,11,11,7,11,3,3,1,1,1,1,13,13,13,12,12,7,12,13,1" function title:update() self.fidx += 0.2 if (self.fidx>#titleglow) self.fidx=1 self.fcol=titleglow[self.fidx\1] end function title:draw() rect(0,0,52,6,8) print("panel extreme", 1, 1, self.fcol) end __gfx__ 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000011010101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000001d5151515d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000151010101510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000151000000510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000151000000510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000010000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000151000000510000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000000001d5151515d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000000000011010101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 __map__ 0102020202020203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 2122222222222223000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000