panel-extreme/panel_extreme.p8

382 lines
11 KiB
Lua

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