diff --git a/panel_extreme.p8 b/panel_extreme.p8 new file mode 100644 index 0000000..20c5fa2 --- /dev/null +++ b/panel_extreme.p8 @@ -0,0 +1,381 @@ +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. +------------------------------- + +------------------------------- +-- credits - +------------------------------- +-- wysiwyg p8scii control - +-- code editor (used for all - +-- fancy text) -- eeooty - +-- https://www.lexaloffle.com/bbs/?tid=52315 +------------------------------- + +-- 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]) + + -- hi-color mode: 15 is bg + -- set color 15 to gradient background + poke(0x5f5f,0x3f) + --blend lines + memset(0x5f70,0xaa,16) + + 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 +-- title +-- (currently a placeholder) + +function init_title() + + pal({[0]=0x82,0x82,0x84,0x84,4,4,0x89,0x89,0x8e,0x8e,0x8f,0x8f,15,15,0x87,0x87},2) + + return view.of{ + bg.new{c=15}, + view.new{ + views=printz"⁶j30⁵ii⁶w⁶tᶜ9a e\n⁶j00⁵ijᶜcp n l\n⁶j04³iᶜ2extreme\n⁶j04³i⁶=ᶜeextreme\n⁶j04³hᶜ8extreme\n\0", + update = function(self) + self.y=20+8*sin(time()/2.1) + self.x=32+6*cos(time()/3.7) + 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) + local v = self.views + 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 +-- panel drawing + +-- panel in ordinary state +panel = { + -- plt: palette as table + -- sx, sy: ulc of emblem on + -- sprite sheet + -- ey: y offset for emblem; + -- usually 2, can wiggle + -- as: animation state + -- 0 == plain + -- negative == mid-fall + -- positive == bounce + -- frames left +} +mknew(panel) + +jiggle = split"3,3,3,2,2,2,3,3,2,2,1,1,2,2,3,3,2,1" + +-- palettes for blocks: +-- lit, bg, shadow, emblem. +-- declared separately to +-- avoid reconstructiong for +-- every panel spawned +redblkp = {9,8,3,7} +ylwblkp = {10,9,4,7} +grnblkp = {6,11,3,7} +blublkp = {7,12,13,7} +prpblkp = {14,13,2,7} + +newblock = { + function() + return panel.new{ + plt=redblkp, + sx=83,sy=1, + ey=2, as=0, + } + end, + function() + return panel.new{ + plt=ylwblkp, + sx=83,sy=11, + ey=2,as=0, + } + end, + function() + return panel.new{ + plt=grnblkp, + sx=78,sy=11, + ey=2,as=0, + } + end, + function() + return panel.new{ + plt=blublkp, + sx=83,sy=6, + ey=2,as=0, + } + end, + function() + return panel.new{ + plt=prpblkp, + sx=73,sy=11, + ey=2,as=0, + } + end, +} + +function panel:update() + local dat_as = self.as + if (dat_as < 0) self.ey = 1 + if (dat_as == 0) self.ey = 2 + if dat_as > 0 then + self.ey = jiggle[dat_as] + self.as -= 1 + end +end + +function panel:draw() + pal(self.plt) + sspr(72,0,9,9) + sspr(self.sx,self.sy, + 5,5, + 2,self.ey) +end +-->8 +-- general drawing +function printz(str) + return {draw=function() + print(str, 0, 0) + end} +end +__gfx__ +0000000000000000000000000000000009999900066666000eeeee00077777000aaaaa0001111111000000000000000000000000000000000000000000000000 +00000000000000000000000000000000988888206bbbbb30eddddd207cccccd0a999994012222222300040400000000000000000000000000000000000000000 +00700700000000000000000000000000987878206b77bb30edd7dd207c7cccd0a979794012222222300444440000000000000000000000000000000000000000 +00077000000000000000000000000000987778206b777b30ed777d207c77ccd0a997994012222222300444440000000000000000000000000000000000000000 +00077000000000000000000000000000988788206bb77b30edd7dd207c777cd0a979794012222222300044400000000000000000000000000000000000000000 +00700700000000000000000000000000988888206bbbbb30eddddd207cccccd0a999994012222222300004000000000000000000000000000000000000000000 +000000000000000110101011000000000222220003333300022222000ddddd000444440012222222300444440000000000000000000000000000000000000000 +000000000000001d5151515d10000000000000000000000000000000000000000000000012222222300444400000000000000000000000000000000000000000 +00000000000000151010101510000000011111004040440004000400000000000000000003333333000444000000000000000000000000000000000000000000 +00000000000000010000000100000000122222304440444044404440000000000000000000000000000440000000000000000000000000000000000000000000 +00000000000000151000000510000000122222300400044040400400007070000000000000000000000400000000000000000000000000000000000000000000 +00000000000000010000000100000000122222300000000000000000007070000000000000040004440004000000000000000000000000000000000000000000 +00000000000000151000000510000000122222304040400004004440000000000000000000444044444044400000000000000000000000000000000000000000 +00000000000000010000000100000000122222300400440040404040007770000000000004444444444044400000000000000000000000000000000000000000 +00000000000000151000000510000000033333004040444004004440000000000000000000444044444444440000000000000000000000000000000000000000 +000000000000001d5151515d10000000000000000000000000000000000000000000000000040004440444440000000000000000000000000000000000000000 +00000000000000011010101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +__map__ +0102020202020203000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +1112121212121213000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +2122222222222223000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000