113 Commits

Author SHA1 Message Date
789cdf6a7a profile the drawing options 2025-06-08 17:36:50 -07:00
372133c15e sqrt is actually faster 2025-06-08 16:55:15 -07:00
b38ebcc603 magnitest: cover image, png file 2025-06-08 16:16:16 -07:00
d9a10a7d07 fastest sqrt version, fix percentage 2025-06-08 16:14:18 -07:00
3ec786f416 fix deceleration 2025-06-08 15:11:36 -07:00
9955df6844 fix scaling alg 2025-06-08 15:11:07 -07:00
9e52e65ad1 fix font color 2025-06-08 15:10:12 -07:00
a9765bee1a fix missed cls 2025-06-08 15:09:27 -07:00
b919eb824d testing vector magnitude calculation 2025-06-08 15:08:58 -07:00
2c37784ad7 try this linefill func and start optimizing it 2025-06-08 14:35:49 -07:00
37d9e3d30e more experiments with drawing these collision boxes. still sucks 2025-06-08 14:10:23 -07:00
1ef5b56c58 wait this version of zot actually looks good 2025-06-01 23:46:59 -07:00
44fb8482a5 a version of zot that does not look awful
performance impact is probably not acceptable though
2025-06-01 23:29:03 -07:00
62f8f27829 a zot prototype that looks awful
I need to draw all the hot parts last
2025-06-01 23:06:44 -07:00
542acc5308 nano-optimizations 2025-06-01 21:03:04 -07:00
4e66c875ad improve legibility 2025-06-01 20:58:21 -07:00
812d32e70c micro-optimizations 2025-06-01 20:58:12 -07:00
d2ec1b39df Show approximation of contact zone 2025-06-01 20:38:56 -07:00
a3ac8074ae line-box collision implemented by Pyrex&Nyeo 2025-06-01 20:29:02 -07:00
85d28ae28b get rid of pships
lots of things rely on exactly one primary ship now, so this was just
overhead and wasted tokens / cspace.
2025-06-01 17:55:46 -07:00
c514c61b3a look at me. *look at me.* I'm the gun_base now 2025-06-01 17:41:07 -07:00
9be828dd5c blast gun is a trig gun
now there are no more base guns
2025-06-01 17:38:45 -07:00
2b51a3472b protron trig gun 2025-06-01 17:36:15 -07:00
95ea70baae vulcan_gun as trig gun
causes x offset to reverse for negative aim; may need to be careful
with how I make aiming guns actually work, but this should work for
deriving player guns from enemy guns (by using negative aim)!
2025-06-01 17:26:29 -07:00
b18b4f885d trig zap gun; fixes
use the trig gun for the zap gun
2025-06-01 17:00:28 -07:00
2fdb8d1a05 trigenometry gun prototype 2025-06-01 16:48:39 -07:00
fc1f84fa28 Delete slip behavior 2025-06-01 16:15:46 -07:00
93b63a5831 Prevent new calls that won't work as expected 2025-06-01 16:11:35 -07:00
297e6e4996 implement clip reload time
two tiers of cooldowns, pretty much
2025-06-01 15:55:11 -07:00
9b3120c47b rewrite mknew to inherit fields before init
I am horrified to admit that C++'s constructor static initialization
list syntax abruptly makes sense to me and I understand the problem
it is trying to solve
2025-06-01 15:53:50 -07:00
abee6d1206 fix skirmisher sparks 2025-05-31 23:44:36 -07:00
3151db5430 fix precedence error 2025-05-31 22:27:03 -07:00
2964159858 fix offset, try but fail to fix variants 2025-05-31 22:19:35 -07:00
95d4b6eb37 what the hell was I thinking when I wrote this 2025-05-31 22:06:48 -07:00
96312e3adf fix offset bugs 2025-05-31 22:05:47 -07:00
bf9a45d87e fix gframe unit 2025-05-31 21:55:21 -07:00
36f7c6572f fix ship spawning 2025-05-31 21:54:02 -07:00
45b70d3aca did you know that 4 is not 1? mindboggling! 2025-05-31 21:43:51 -07:00
35980d801a forgot my increments! 2025-05-31 21:40:17 -07:00
734811bd62 math works better when you return your values 2025-05-31 21:33:06 -07:00
4fddbea82c use the right loader 2025-05-31 21:31:20 -07:00
f675e31967 oops, I accidentally 2025-05-31 21:30:30 -07:00
0bd1463416 replace demo level with infinite copies of flotilla 0 2025-05-31 21:29:54 -07:00
267f8a3667 actually add ships we keep 2025-05-31 21:02:26 -07:00
fa206c37c5 "redistribute"-type flotilla: update 2025-05-31 21:00:27 -07:00
928e7f7418 prototype flotilla loader 2025-05-31 20:39:07 -07:00
2439fda068 ship prototype tweaks 2025-05-31 20:38:59 -07:00
d13290f438 placeholder flotilla ships 2025-05-31 19:03:38 -07:00
e3a2810f0a Prototype a flotilla template. 2025-05-25 21:03:51 -07:00
3764063b20 abandon "offset" sprites, use "row tier" sprites 2025-05-25 20:49:27 -07:00
90f6df2922 flotilla notes and sprites 2025-05-25 19:11:44 -07:00
b7c3e6ee92 adjust menu renderer 2025-05-03 17:26:48 -07:00
c91e5f4bd1 shorten RATE message
not enough room to describe "fractions add up" -- maybe I can just fit
in the "remainder" to hint that it will be considered in future
upgrades?
2025-05-03 17:19:33 -07:00
ea2ddadb15 oops, method call syntax is special 2025-05-03 17:12:20 -07:00
9333c03bf3 add main gun rate upgrade to ship pool 2025-05-03 17:11:47 -07:00
1b45bd3dc3 fix rate formatting 2025-05-03 17:11:35 -07:00
71a7351d77 oops, miscalculated box width 2025-05-03 17:04:29 -07:00
80bb848468 options work better when I return them 2025-05-03 16:51:59 -07:00
b227844d12 Restyle ship stat upgrades. 2025-05-03 16:48:18 -07:00
ce14d03669 offer gun upgrades 2025-05-03 16:38:39 -07:00
ccd2c64103 update gun pick description style 2025-05-03 16:38:26 -07:00
e5b8a30cb6 cooldown reduction prototype
I decided to keep cooldown in the same unit as the frame counter,
because the extra math when calculating an upgrade is going to happen
much less frequently than actual cooldown checks and calculations, so
leaving the upgrade logic as the less efficient path seems like the
more appropriate choice.
2025-05-03 16:28:54 -07:00
7ed305d2d9 Ammo quantity upgrade prototype
Not yet tested. Will crash until I also get rate_upgrade_opt up.
2025-05-03 16:06:16 -07:00
288b7f64c8 tinker with blip colors, go back to level+1
with the current testing level, level + 1 is necessary to comfortably
get a weapon before the Wall O' Block shows up
2025-01-26 22:32:17 -08:00
aea2a8c481 red blip when shield exhausted 2025-01-26 22:27:14 -08:00
9b24f10c23 inline ow, simplify blip, no shield piercing
* any amount of shielding prevents all HP damage
* when shields are sent to 0, orange blip
* all blips are 3 frames

considering a "shimmy" animation for start of shield recovery. maybe later
2025-01-26 22:25:06 -08:00
511c18f90e remove offset when choosing category of upgrade 2025-01-26 22:15:03 -08:00
142810ee2d scatter xp drops more 2025-01-26 22:11:02 -08:00
50beae1852 don't attract xp when dead 2025-01-26 22:08:16 -08:00
9c95fc1784 suck! suck! suck! suck! suck! suck! suck! suck! 2025-01-26 21:00:39 -08:00
cb2d24c9d0 thrust performance is now also an option 2025-01-26 20:38:31 -08:00
67603f8496 start of normal ship upgrades
todo: thrust upgrade
2025-01-26 20:21:06 -08:00
2cebea663f make stat modifications actually work 2025-01-26 13:14:59 -08:00
eed7b6af87 unique bullet base instances
peel off new copies of ammo when using a new gun so we can upgrade it without screwing up the base stats
2025-01-26 13:07:43 -08:00
26c3a5b91e actually fix starting ammo
also improve box overflow
2025-01-26 12:50:27 -08:00
44c70a028f fix starting ammo 2025-01-26 12:45:43 -08:00
a90caeba85 make level less spewy, finish renaming s to icon 2025-01-26 12:42:57 -08:00
cd5b79ef4a prototype: gun picking 2025-01-26 11:21:32 -08:00
637eed1eb8 autofire and three guns 2025-01-26 01:06:37 -08:00
55ab256539 oh right I changed that name 2025-01-26 00:32:17 -08:00
22d13121a9 placeholders for card draw 2025-01-26 00:30:09 -08:00
58da8e6dc3 fix hokey pokey menu
the menu eases in, the menu eases out, the menu eases in and you shake it all about
2025-01-20 18:02:50 -08:00
8ff0732cbc draw rearm pane; exit behavior is broken
Nil transparency has screwed me over; I am uploading this version as
an illustrative example
2025-01-20 17:43:21 -08:00
c88e7c0657 I really wish Lua had real classes rather than forcing you to assemble it yourself 2025-01-20 17:09:47 -08:00
ff3552bc45 fix unit error for xp frame logic 2025-01-20 17:02:02 -08:00
2dcb95b0cd menu prototype 2025-01-20 16:59:57 -08:00
87451bbd3a incomplete start to porting ui 2025-01-12 22:58:20 -08:00
89a42e6c8b improve xp gem art 2025-01-12 21:51:32 -08:00
e2be11a2da fix order of magnitude error in XP logic 2025-01-12 21:47:11 -08:00
175099d778 make maxval work better near p8 precision limits 2024-12-29 23:44:39 -08:00
33fede4ed8 update comment about off-by-1 error 2024-12-29 23:41:47 -08:00
afa1f22170 go back to 0x0.0001 increments for xp
I foresee the 32K limit being a bigger problem than the math in vertmeter, although I will probably need to go patch vertmeter up too
2024-12-29 23:39:56 -08:00
78b200272e fix shield crash 2024-12-29 23:33:45 -08:00
42ac2abc20 groundwork for full mode switching 2024-12-29 23:26:48 -08:00
c55ea000fd whoosh animation when level up pending 2024-12-28 19:56:42 -08:00
2c1ad0a0b3 drop xp gems 2024-12-28 19:27:54 -08:00
e0b784ce7d clean up, run at 60 fps
now the bounce animation feels like it takes too long, trying to fix it
2024-12-26 17:43:04 -08:00
e1a70cc6fc dark blue, not dark gray, for pane bg 2024-12-26 17:16:48 -08:00
cbdf2a27cd fast quadratic exit feels better 2024-12-26 17:05:55 -08:00
caaf848722 fixed it 2024-12-26 16:59:43 -08:00
25f58d5cce messed up entry animation but it's a start
* wrong Y positions for everything
* both directions are "enter"
2024-12-26 16:19:52 -08:00
c15ec61494 partial prototype of object-oriented drawing and entry 2024-12-26 12:32:31 -08:00
7ff5cf97ad functioning prototype 2024-12-24 19:23:14 -08:00
f761d1a172 prototype for REARM screen UI 2024-12-24 19:04:07 -08:00
98f56328a6 off by 1 2024-12-24 18:10:48 -08:00
93792c36c9 sketch for possible REARM ui blank 2024-12-24 18:10:17 -08:00
d799947c46 it would hlep if I actually removed the old text 2024-12-24 15:06:18 -08:00
f3a84573e6 remove readme from .p8 into a separate .md file 2024-12-24 15:04:23 -08:00
1a7bc7094e HP/XP labels look much better and correctly-associated now 2024-10-27 13:16:37 -07:00
39d53c45aa xp and hp brighter and closer to meters 2024-09-07 16:36:30 -07:00
5870c129eb staggered "xp", "hp" labels in UI 2024-09-07 16:33:58 -07:00
68863280f3 stagger the bars 2024-09-07 16:17:38 -07:00
3f7c4f59c0 stretch meter area 2024-09-07 16:15:00 -07:00
8 changed files with 3220 additions and 1004 deletions

229
collisiontest.p8 Normal file
View File

@ -0,0 +1,229 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
bx0=0
by0=0
bx1=127
by1=127
lx0=0
ly0=0
lx1=127
ly1=127
-->8
function collides()
local tmin,tmax=0,1
local ldx,ldy=lx1-lx0,ly1-ly0
-- x
if ldx==0 then
if (lx0<bx0 or lx0>bx1) return
else
local tx0=(bx0-lx0)/ldx
local tx1=(bx1-lx0)/ldx
if (tx0 > tx1) tx0,tx1=tx1,tx0
if (tmin < tx0) tmin=tx0
if (tmax > tx1) tmax=tx1
end
if ldy==0 then
if (ly0<by0 or ly0>by1) return
else
local ty0=(by0-ly0)/ldy
local ty1=(by1-ly0)/ldy
if (ty0 > ty1) ty0,ty1=ty1,ty0
if (tmin < ty0) tmin=ty0
if (tmax > ty1) tmax=ty1
end
if (tmax < tmin) return
return tmin,tmax
end
-->8
function _init()
poke(0x5f2d,1) -- enable mouse
end
function _bounce_screen(x)
return _bounce(x*128,128)
end
function _bounce(x,mx)
x=x%(mx * 2)
if (x>=mx)return mx-(x-mx)
return x
end
function _to_halfopen(x0,x1)
-- turn two numbers into a
-- half-open integer range
x0=flr(x0)
x1=flr(x1)
local lo=min(x0,x1)
local hi=max(x0,x1)
if (hi==lo) return lo,hi
return lo,hi-1
end
function _update60()
local t=time()/16
local bx0_=_bounce_screen(t*1)
local by0_=_bounce_screen(t*2)
local bx1_=_bounce_screen(t*3)
local by1_=_bounce_screen(t*4)
bx0,bx1=_to_halfopen(bx0_,bx1_)
by0,by1=_to_halfopen(by0_,by1_)
update_line()
--[[
local lx0_=_bounce_screen(t*1.5)
local ly0_=_bounce_screen(t*2.5)
local lx1_=_bounce_screen(t*3.5)
local ly1_=_bounce_screen(t*4.5)
lx0,lx1=lx0_,lx1_
ly0,ly1=ly0_,ly1_
]]--
end
was_down=false
last_mx,last_my=nil,nil
function update_line()
local mx,my=stat(32),stat(33)
local is_down=stat(34)!=0
if is_down then
if was_down then
lx1,ly1=mx,my
else
lx0,ly0=mx,my
end
end
was_down=is_down
last_mx,last_my=mx,my
end
-->8
function _draw()
cls(0)
rect(bx0,by0,bx1,by1,6)
--quickzot(lx1,ly1,2,lx1-lx0,ly1-ly0,10,9,8)
linefill(lx0, ly0, lx1, ly1, 2, 9)
line(lx0,ly0,lx1,ly1,2)
local cmin, cmax = collides()
if cmin then
local dx,dy=lx1-lx0,ly1-ly0
line(lx0 + dx*cmin,
ly0 + dy*cmin,
lx0 + dx*cmax,
ly0 + dy*cmax,
11)
pset(lx0 + dx*cmin,
ly0 + dy*cmin,
12)
end
pset(last_mx,last_my,7)
end
-->8
function zot_one(x, y, r, ir, dx, dy, hot, warm)
local x0, y0 = x-dx, y-dy
local rx,ry,irx,iry=r*sgn(dx),r*sgn(dy),ir*sgn(dx),ir*sgn(dy)
if warm then
line(x0+irx,y0-ry,x+rx,y-iry,warm)
line(x0-rx,y0+iry,x-irx,y+ry,warm)
--line(x0-rx,y0-ry,x+rx,y+ry,warm)
end
line(x0,y0,x+rx,y-iry,hot)
line(x0,y0,x-irx,y+ry,hot)
--line(x0,y0,x+rx,y+ry,hot)
end
function zot(x,y,r,dx,dy,hot,warm,cold)
local x0,y0,sdx,sdy=x-dx,y-dy,sgn(dx),sgn(dy)
local rx,ry=r*sdx,r*sdy
if cold then
rectfill(x0-rx,y0-ry,x0+rx,y0+ry,cold)
local sdxh,sdyh=sdx/2,sdy/2
line(x0-rx-sdxh,y0+ry+sdyh,x-rx,y+ry,cold)
line(x0+rx+sdxh,y0-ry-sdyh,x+rx,y-ry,cold)
end
for i=-r,r do
line(x0+i*sdx,y0-ry,x+rx,y-i*sdy,warm)
line(x0-rx,y0+i*sdy,x-i*sdx,y+ry,warm)
end
for i=-r,r do
line(x0,y0,x+rx,y-i*sdy,hot)
line(x0,y0,x-i*sdx,y+ry,hot)
end
end
function quickzot(x,y,r,dx,dy,hot,warm,cold)
local x0, y0, r2 = x-dx, y-dy, r/2
rectfill(x0-0.5-r2, y0-0.5-r2, x0+r2+0.5, y0+r2+0.5, cold)
local a = atan2(dx,dy)-0.25
local tdx,tdy=cos(a), sin(a)
for i=-r*0.65,r*0.65,0.65 do
line(x0+i*tdx, y0+i*tdy, x+i*tdx, y+i*tdy, warm)
end
rectfill(x-r2,y-r2,x+r2,y+r2,hot)
end
-- linefill x0 y0 x1 y1 r [col]
-- draw a thicc line
-- https://www.lexaloffle.com/bbs/?tid=39016
function linefill(ax,ay,bx,by,r,c)
if(c) color(c)
local dx,dy=bx-ax,by-ay
-- avoid overflow
-- credits: https://www.lexaloffle.com/bbs/?tid=28999
local d,n = abs(dx),abs(dy)
if (d<n) d,n=n,d
n/=d
d*=sqrt(n*n+1)
if(d<0.001) return
local ca,sa=dx/d,-dy/d
-- polygon points
local s={
{0,-r},{d,-r},{d,r},{0,r}
}
local u,v,spans=s[4][1],s[4][2],{}
local x0,y0=ax+u*ca+v*sa,ay-u*sa+v*ca
for i=1,4 do
local u,v=unpack(s[i])
local x1,y1=ax+u*ca+v*sa,ay-u*sa+v*ca
local _x1,_y1=x1,y1
if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0
local dx=(x1-x0)/(y1-y0)
if(y0<0) x0-=y0*dx y0=-1
local cy0=y0\1+1
-- sub-pix shift
x0+=(cy0-y0)*dx
for y=y0\1+1,min(y1\1,127) do
-- open span?
local span=spans[y]
if span then
rectfill(x0,y,span,y)
else
spans[y]=x0
end
x0+=dx
end
x0,y0=_x1,_y1
end
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

245
magnitest.p8 Normal file
View File

@ -0,0 +1,245 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
--magnitest.p8
--accuracy and perf tests for
--vector calculation logic
-- profiler says 67 cycles
-- 39 lua, 28 system
function bbs28999alg(dx, dy)
local d = max(abs(dx),abs(dy))
local n = min(abs(dx),abs(dy)) / d
return sqrt(n*n + 1) * d
end
-- profiler says 56 cycles
-- 24 lua, 32 system
function bbs28999algopt(dx, dy)
local d,n=abs(dx),abs(dy)
if (d<n) d,n=n,d
n/=d
return (n*n + 1)^0.5 * d
end
-- profiler says 54 cycles
-- 26 lua, 28 system
function bbs28999algopt2(dx, dy)
local d,n=abs(dx),abs(dy)
if (d<n) d,n=n,d
n/=d
return sqrt(n*n + 1) * d
end
-- profiler says 18 cycles
-- 18 lua, 0 system
function trigalg(dx, dy)
local s = sin(atan2(dx,dy))
if (s==0) return abs(dx)
return abs(dy/s)
end
-->8
function _init()
gdx,gdy=0,0
acc=1
magnitude = 1
tresult=0
bresult=0
delta=0
dp=0
end
function _update60()
if (btn(0)) gdx -= acc
if (btn(1)) gdx += acc
if (btn(2)) gdy -= acc
if (btn(3)) gdy += acc
if (btn(4) and btn(5)) gdx,gdy=0,0
gdx=mid(-16000,16000,gdx)
gdy=mid(-16000,16000,gdy)
if btn() == 0 or btn(4) then
acc = 1
elseif btn(5) then
acc *= 1.05
else
acc *= 1.02
end
if (acc > 1024) acc=1024
local a,b=abs(gdx),abs(gdy)
if (b>a) a,b=b,a
magnitude = 1
while magnitude < a/64 do
magnitude *= 2
end
bresult=bbs28999algopt2(gdx,gdy)
tresult=trigalg(gdx,gdy)
delta=tresult-bresult
dp=(2*abs(delta)/abs(abs(bresult)+abs(tresult)))*100
if (delta == 0) dp=0
end
cols = {
6,7,
[4]=10,
[8]=9,
[16]=4,
[32]=14,
[64]=15,
[128]=11,
[256]=12,
[512]=13,
[1024]=8,
}
function _draw()
cls()
camera()
print("x: "..tostr(gdx).." y: "..tostr(gdy).."\nbase: "..tostr(bresult).."\ntrig: "..tostr(tresult).."\n\ndiff: "..tostr(delta).."\n %:"..tostr(dp),0,0,13)
print("⬆️⬇️⬅️➡️:move ❎:fast 🅾️:slow\n❎+🅾️:reset position",0,117,12)
camera(-63,-63)
line(0,0,gdx/magnitude,gdy/magnitude,cols[magnitude] or 2)
rectfill(0,0,gdx/magnitude,0,5)
rectfill(0,0,0,gdy/magnitude,5)
end
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__label__
d0d000000000ddd0ddd0ddd0d0d00000ddd0d0d0ddd0ddd000000000d0d0000000000000dd00dd00ddd0ddd00000ddd0ddd0ddd0ddd000000000000000000000
d0d00d00000000d000d0d000d0d00000d0d0d0d000d000d000000000d0d00d00000000000d000d0000d0d0000000d0d0d000d000d00000000000000000000000
0d00000000000dd000d0ddd0ddd00000d0d0ddd0ddd000d000000000ddd000000000ddd00d000d00ddd0ddd00000ddd0ddd0ddd0ddd000000000000000000000
d0d00d00000000d000d000d000d00000d0d000d0d00000d00000000000d00d00000000000d000d00d00000d00000d0d000d000d000d000000000000000000000
d0d000000000ddd000d0ddd000d00d00ddd000d0ddd000d000000000ddd0000000000000ddd0ddd0ddd0ddd00d00ddd0ddd0ddd0ddd000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ddd0ddd00dd0ddd000000000ddd0ddd0dd00ddd00000dd00ddd0ddd0dd0000000000000000000000000000000000000000000000000000000000000000000000
d0d0d0d0d000d0000d00000000d0d0d00d00d0d000000d00d0d000d00d0000000000000000000000000000000000000000000000000000000000000000000000
dd00ddd0ddd0dd00000000000dd0ddd00d00ddd000000d00ddd000d00d0000000000000000000000000000000000000000000000000000000000000000000000
d0d0d0d000d0d0000d00000000d000d00d0000d000000d00d0d000d00d0000000000000000000000000000000000000000000000000000000000000000000000
ddd0d0d0dd00ddd000000000ddd000d0ddd000d00d00ddd0ddd000d0ddd000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ddd0ddd0ddd00dd000000000ddd0ddd0dd00ddd00000ddd0dd00ddd0ddd000000000000000000000000000000000000000000000000000000000000000000000
0d00d0d00d00d0000d00000000d0d0d00d00d0d00000d0d00d00d00000d000000000000000000000000000000000000000000000000000000000000000000000
0d00dd000d00d000000000000dd0ddd00d00ddd00000d0d00d00ddd0ddd000000000000000000000000000000000000000000000000000000000000000000000
0d00d0d00d00d0d00d00000000d000d00d00d0d00000d0d00d0000d0d00000000000000000000000000000000000000000000000000000000000000000000000
0d00d0d0ddd0ddd000000000ddd000d0ddd0ddd00d00ddd0ddd0ddd0ddd000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
dd00ddd0ddd0ddd0000000000000dd000000dd00ddd0dd00ddd00000000000000000000000000000000000000000000000000000000000000000000000000000
d0d00d00d000d0000d00000000000d0000000d0000d00d00d0d00000000000000000000000000000000000000000000000000000000000000000000000000000
d0d00d00dd00dd0000000000ddd00d0000000d0000d00d00ddd00000000000000000000000000000000000000000000000000000000000000000000000000000
d0d00d00d000d0000d00000000000d0000000d0000d00d0000d00000000000000000000000000000000000000000000000000000000000000000000000000000
ddd0ddd0d000d000000000000000ddd00d00ddd000d0ddd000d00000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000d0d00000ddd00000ddd0ddd0ddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000d00d00d0d00000d0d000d0d0d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000d000000d0d00000d0d0ddd0ddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000d0000d00d0d00000d0d0d00000d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000d0d00000ddd00d00ddd0ddd000d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000ff000000
000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000fff00000000
00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000000ffff00000000000
00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000000fff000000000000000
00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000000fff000000000000000000
00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000000fff000000000000000000000
00000000000000000000000000000000000000000000000000000000000000050000000000000000000000000000000000000fff000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000ffff000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000fff0000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000fff0000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000005000000000000000000000000fff0000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000500000000000000000000ffff0000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000500000000000000000fff00000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000500000000000000fff00000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000500000000000fff00000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000500000000fff00000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000050000ffff00000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000050fff000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000055555555555555555555555555555555555555555555555555555555555000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0ccccc000ccccc000ccccc000ccccc000000ccc00cc0c0c0ccc0000000000ccccc000000ccc0ccc00cc0ccc000000ccccc0000000cc0c0000cc0c0c000000000
ccc0ccc0cc000cc0ccc00cc0cc00ccc00c00ccc0c0c0c0c0c00000000000cc0c0cc00c00c000c0c0c0000c000000cc000cc00c00c000c000c0c0c0c000000000
cc000cc0cc000cc0cc000cc0cc000cc00000c0c0c0c0c0c0cc0000000000ccc0ccc00000cc00ccc0ccc00c000000cc0c0cc00000ccc0c000c0c0c0c000000000
cc000cc0ccc0ccc0ccc00cc0cc00ccc00c00c0c0c0c0ccc0c00000000000cc0c0cc00c00c000c0c000c00c000000cc000cc00c0000c0c000c0c0ccc000000000
0ccccc000ccccc000ccccc000ccccc000000c0c0cc000c00ccc0000000000ccccc000000c000c0c0cc000c0000000ccccc000000cc00ccc0cc00ccc000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0ccccc0000000ccccc000000ccc0ccc00cc0ccc0ccc00000ccc00cc00cc0ccc0ccc0ccc00cc0cc00000000000000000000000000000000000000000000000000
cc0c0cc00c00cc000cc00c00c0c0c000c000c0000c000000c0c0c0c0c0000c000c000c00c0c0c0c0000000000000000000000000000000000000000000000000
ccc0ccc0ccc0cc0c0cc00000cc00cc00ccc0cc000c000000ccc0c0c0ccc00c000c000c00c0c0c0c0000000000000000000000000000000000000000000000000
cc0c0cc00c00cc000cc00c00c0c0c00000c0c0000c000000c000c0c000c00c000c000c00c0c0c0c0000000000000000000000000000000000000000000000000
0ccccc0000000ccccc000000c0c0ccc0cc00ccc00c000000c000cc00cc00ccc00c00ccc0cc00c0c0000000000000000000000000000000000000000000000000

BIN
magnitest.p8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

356
old_readme.md Normal file
View File

@ -0,0 +1,356 @@
This file contains text that used to be in the cartridge itself, but
I'm getting increasingly anxious about cartridge space so I'm moving
it out ot a separate file.
---
main loop sequence
==================
1. level_frame
2. events
3. merge new_events into events
4. update bg intangibles
5. move ships (player first)
6. move bullets (player first)
7. calculate collisions
1. pship on eship
2. ebullet on pship
3. pbullet on eship
8. update fg intangibles
9. check for end of level
draw order
----------
bottom to top:
1. intangibles_bg
2. player bullets
3. player ships
4. enemy ships
5. enemy bullets
6. intangibles_fg
notes
-----
intangibles_fg move()s after
all collisions and other moves
are processed. if an intangible
is added to the list as a result
of a collision or move, it will
itself be move()d before it is
drawn.
data-driven items
=================
guns and bullets both allow the
most common behaviors to be
expressed with data alone.
ships only need a movement
algorithm expressed.
guns
----
* t - metatable for bullet type.
fired once in the bullet's
default direction per shot.
* enemy - if true, fired bullets
are flagged as enemy bullets.
* icon - sprite index of an
8x8 sprite to display in the
hud when the player has this
gun. default is 20, a generic
crosshair bullseye thing.
* cooldown - min frames between
shots.
* ammo, maxammo - permitted
number of shots. 0 is empty
and unfireable. maxammo = 0
will cause a divide by zero
so don't do that. if nil,
ammo is infinite.
default guns manage ammo and
cooldown in shoot, then call
actually_shoot to create the
projectile. override only
actually_shoot to change
projectile logic while keeping
cooldown and ammo logic.
bullets
-------
* dx, dy - movement per frame.
player bullets use -dy
instead.
* enemyspd - multiplier for dx
and dy on enemy bullets.
default is 0.5, making enemy
shots much easier to dodge
* damage - damage per hit;
used by ships
* sprite - sprite index.
* x_off, y_off - renamed for
the next two vars. may revert
* center_off_x - the horizontal
centerpoint of the bullet,
for positioning when firing.
assume a pixel's coordinates
refer to the upper left corner
of the pixel; the center of
a 2-width bullet with an
upper left corner at 0 is 1,
not 0.5.
* top_off_y, bottom_off_y -
also for positioning when
firing. positive distance from
top or bottom edge to image.
top_off_y will usually be 0,
bottom_off_y will not be when
bullets are smaller than
the sprite box.
* width, height - measured in
full sprites (8x8 boxes), not
pixels. used for drawing.
bullets despawn when above or
below the screen (player or
enemy bullets, respectively).
by default, bullets despawn
when they hit something.
override hitship to change this.
ships
____
ships move by calculating
momentum, then offsetting their
position by that momentum, then
clamping their position to the
screen (horizontally only for
ships that autoscroll). ships
that autoscroll (slip==true)
then slide down by scrollspeed.
fractional coordinates are ok.
after movement, ships lose
momentum (ship.drag along each
axis). abs(momentum) can't
exceed ship.maxspeed.
ships gain momentum by acting
like a player pushing buttons.
the player ship actually reads
buttons for this.
act -- returns new acceleration:
dx, dy, shoot_spec, shoot_main.
dx and dy are change in momentum
in px/frame. this is controls
only -- friction is handled in
ship:move (`drag` value).
ships hitting another ship take
1 damage per frame of overlap.
ships hitting a bullet check
bullet.damage to find out how
much damage they take. damage
is applied to shields, then hp.
damaged ships flash briefly -
blue (12) if all damage was
shielded, white (7) if hp was
damaged. a ship that then has 0
or less hp calls self:die() and
tells the main game loop to
remove it.
shieldcooldown is the interval
between restoring shield points.
shieldpenalty is the delay
before restoring points after
any damage, reset to this value
on every damaging hit (whether
it is absorbed by the shield or
not) -- shield behaves like
halo and other shooters in its
heritage, where it recovers if
you avoid damage for a while.
not that there is any safe cover
in this kind of game.
ships do not repair hp on their
own. negative-damage bullets
are treated as 0, but a bullet
can choose to repair the ship
it hits in its own hitship
method, or otherwise edit it
(changing weapons, refilling
weapon ammo). powerups are
therefore a kind of bullet.
levels
======
a level is a table mapping
effective frame number to
functions. when a level starts,
it sets lframe ("level frame")
and distance to 0.
every frame, level_frame
increments lframe by 0x0.0001.
then if the level is not frozen,
it increments distance by 1.0
and runs the function in the
level table for exactly that
frame number (if any). distance
is therefore "nonfrozen frames",
and is used to trigger level
progress. lframe always
increments. ships are encouraged
to use lframe to control
animation and movement, and may
use distance to react to level
progress separately from overall
time. remember to multiply
lframe-related stuff by 0x0001.
a special sentinel value, eol,
marks the end of the level.
(the level engine doesn't know
when it's out of events, so
without eol, the level will
simply have no events forever.)
when it finds eol, level_frame
throws away the current level
and tells the main loop that it
might be done. the main loop
agrees the level is over and the
player has won when the level
has reached eol and there are
no more enemy ships, enemy
bullets, or background events
remaining. player ships, player
bullets, and intangibles are
not counted.
level freezing
--------------
the level is frozen when the
global value freeze > 0.
generally, something intending
to block level progress (a
miniboss, a minigame, etc.)
increments freeze and prepares
some means of decrementing it
when it no longer wants to block
level progress.
most commonly, we want to block
until some specific ship or
group of ships has died. for
these ships, override ship:die
to decrement freeze. make sure
to set ship.dead in any new
ship:die method so anything else
looking at it can recognize
the ship as dead.
for anything else, you probably
want an event to figure out when
to unfreeze.
levels start at 1
-----------------
distance is initialized to 0
but gets incremented before the
first time the engine looks for
events. therefore, the first
frame of the level executes
level[1]. since levelframe
executes before anything else,
level[1] sets up the first frame
drawn in the level. the player
does not see a blank world
before level[1] runs.
level[1] can therefore be used
to reconfigure the player ship,
set up backgrounds, start music,
kick off some kind of fade-in
animation, etc.
events
======
the global list "events" stores
0-argument functions which are
called every frame. if they
return true, they are removed
from the list and not run again;
if they return false, they stay
and will be called in later
frames. the level does not end
while the events table is
nonempty.
events are most commonly used
to set up something for later
(for example, blip uses an event
to remove the fx_pallete from
the flashing ship when the blip
expires), but can also be used
to implement a "level within a
level" that does something
complicated until it's done. if
you froze the level when
creating the event, remember
to thaw it (freeze -= 1) on all
paths that return true.
to do complex stuff in events,
use a closure or a metatable
that specifies __call.
to avoid editing the events
list while it is being iterated,
events that create new events
must add those events to
new_events rather than events.
new_events is only valid during
the "event execution" stage, so
events created at any other time
must go directly on events
without using new_events.
intangibles
===========
the intangibles_fg and
intangibles_bg lists contain
items with :move and :draw.
like ships and bullets, they
move during _update60 and
draw during _draw. they are
not checked for collisions.
intangibles_bg moves/draws
before anything else moves or
draws. intangibles_fg
moves/draws last. this controls
whether your intangible object
draws in front of or behind
other stuff. you probably want
intangibles_bg for decorative
elements and intangibles_fg
for explosions, score popups,
etc.
there's no scrolling background
engine but intangibles_bg could
be used to create one, including
using the map (otherwise unused
in this engine) for the purpose.
intangibles do not prevent the
level from ending. like bullets
and ships, if :move returns
true, they are dropped.

501
profiling.p8 Normal file
View File

@ -0,0 +1,501 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
-- prof: cpu cycle counter v1.4
-- BY PANCELOR
--[[------------------------
use this cart to precisely
measure code execution time
--------------------------------
★ overview ★
--------------------------------
| tab 0 | usage guide |
| tab 1 | (internals) |
| tab 2 | your code here |
--------------------------------
-----------------------
-- ★ usage guide ★ --
-----------------------
웃: i have two code snippets;
which one is faster?
🐱: edit the last tab with your
snippets, then run the cart.
it will tell you precisely
how much cpu it takes to
run each snippet.
the results are also copied
to your clipboard.
웃: what do the numbers mean?
🐱: the cpu cost is reported
as lua and system cycle
counts. look up stat(1)
and stat(2) for more info.
if you're not sure, just
look at the first number.
lower is faster (better)
웃: why "{locals={9}}"
in the example?
🐱: accessing local variables
is faster than global vars.
so if your test involves
local variables, simulate
this by passing them in:
prof(function(a)
sqrt(a)
end,{ locals={9} })
/!\ /!\ /!\ /!\
local values from outside
the current scope are also
slower to access! example:
global = 4
local outer = 4
prof(function(x)
local _ = x --fast
end,function(x)
local _ = outer --slow
end,function(x)
local _ = global --slow
end,{ locals={4} })
/!\ /!\ /!\ /!\
웃: can i do "prof(myfunc)"?
🐱: no, this sometimes gives
wrong results! always use
inline functions:
prof(function()
--code for myfunc here
end)
as an example, "prof(sin)"
reports "-2" -- wrong! but
"prof(function()sin()end)"
correctly reports "4"
(see the technical notes at
the start of the next tab
for a brief explanation.
technically, "prof(myfunc)"
will work if myfunc was made
by the user, but you will
risk confusing yourself)
---------------
★ method 2 ★
---------------
this cart is based on
code by samhocevar:
https://www.lexaloffle.com/bbs/?pid=60198#p
if you do this method, be very
careful with local/global vars.
it's very easy to accidentally
measure the wrong thing.
here's an example of how to
measure cycles (ignoring this
cart and using the old method)
function _init()
local a=11.2 -- locals
local n=1024
flip()
local tot1,sys1=stat(1),stat(2)
for i=1,n do end --calibrate
local tot2,sys2=stat(1),stat(2)
for i=1,n do local _=sqrt(a) end --measure
local tot3,sys3=stat(1),stat(2)
function cyc(t0,t1,t2) return ((t2-t1)-(t1-t0))*128/n*256/stat(8)*256 end
local lua = cyc(tot1-sys1,tot2-sys2,tot3-sys3)
local sys = cyc(sys1,sys2,sys3)
print(lua.."+"..sys.."="..(lua+sys).." (lua+sys)")
end
run this once, see the results,
then change the "measure" line
to some other code you want
to measure.
note: wrapping the code inside
"_init()" is required, otherwise
builtin functions like "sin"
will be measured wrong.
(the reason is explained at
the start of the next tab)
---------------
★ method 3 ★
---------------
another way to measure cpu cost
is to run something like this:
function _draw()
cls(1)
local x=9
for i=1,1000 do
local a=sqrt(x) --snippet1
-- local b=x^0.5 --snippet2
end
end
while running, press ctrl-p to
see the performance monitor.
the middle number shows how much
of cpu is being used, as a
fraction. (0.60 = 60% used)
now, change the comments on the
two code snippets inside _draw()
and re-run. compare the new
result with the old to determine
which snippet is faster.
note: every loop iteration costs
an additional 2 cycles, so the
ratio of the two fractions will
not match the ratio of the
execution time of the snippets.
but this method can quickly tell
you which snippet is faster.
]]
-->8
--[[ profiler.lua
more info: https://www.lexaloffle.com/bbs/?tid=46117
usage:
prof(function()
memcpy(0,0x200,64)
end,function()
poke4(0,peek4(0x200,16))
end)
passing locals:
prof(
function(a,b)
local c=(a+1)*(b+1)-1
end,
function(a,b)
local c=a*b+a+b
end,
{locals={3,5}}
)
getting global/local variables exactly right
is very tricky; you should always use inline
functions like above; if you try e.g. prof(sin)
the results will be wrong.
# minutiae / notes to self:
---------------------------
doing this at top-level is awkward:
for _=1,n do end -- calibrate
for _=1,n do sin() end -- measure
b/c sin is secretly local at top-level,
so it gives a misleading result (3 cycles).
do it inside _init instead for a
more representative result (4 cycles).
## separate issue:
------------------
if you call prof(sin), it gives the wrong result (-2 cycles) because
it's comparing sin() against noop() (not truly nothing).
but we want the noop() there for normal inline prof() calls,
to avoid measuring the cost of the indirection
(calling func() from inside prof() is irrelevant to
how cpu-expensive func()'s body is)
]]
-- prof(fn1,fn2,...,fnN,[opts])
--
-- opts.locals: values to pass
-- opts.name: text label
-- opts.n: number of iterations
function prof(...)
local funcs={...}
local opts=type(funcs[#funcs])=="table" and deli(funcs) or {}
-- build output string
local msg=""
local function log(s)
msg..=s.."\n"
end
if opts.name then
log("prof: "..opts.name)
end
for fn in all(funcs) do
local dat=prof_one(fn,opts)
log(sub(" "..dat.total,-3)
.." ("
..dat.lua
.." lua, "
..dat.sys
.." sys)")
end
-- copy to clipboard
printh(msg,"@clip")
-- print + pause
cls()
stop(msg)
end
function prof_one(func, opts)
opts = opts or {}
local n = opts.n or 0x200 --how many times to call func
local locals = opts.locals or {} --locals to pass func
-- we want to type
-- local m = 0x80_0000/n
-- but 8MHz is too large to fit in a pico-8 number,
-- so we do (0x80_0000>>16)/(n>>16) instead
-- (n is always an integer, so n>>16 won't lose any bits)
local m = 0x80/(n>>16)
assert(0x80/m << 16 == n, "n is too small") -- make sure m didn't overflow
local fps = stat(8)
-- given three timestamps (pre-calibration, middle, post-measurement),
-- calculate how many more CPU cycles func() took compared to noop()
-- derivation:
-- T := ((t2-t1)-(t1-t0))/n (frames)
-- this is the extra time for each func call, compared to noop
-- this is measured in #-of-frames -- it will be a small fraction for most ops
-- F := 1/30 (seconds/frame) (or 1/60 if this test is running at 60fps)
-- this is just the framerate that the tests run at, not the framerate of your game
-- M := 256*256*128 = 0x80_0000 = 8MHz (cycles/second)
-- (PICO-8 runs at 8MHz; see https://www.lexaloffle.com/dl/docs/pico-8_manual.html#CPU)
-- cycles := T frames * F seconds/frame * M cycles/second
-- optimization / working around pico-8's fixed point numbers:
-- T2 := T*n = (t2-t1)-(t1-t0)
-- M2 := M/n = (M>>16)/(n>>16) := m (e.g. when n is 0x1000, m is 0x800)
-- cycles := T2*M2*F
local function cycles(t0,t1,t2)
local diff = (t2-t1)-(t1-t0)
local e1 = "must use inline functions -- see usage guide"
assert(0<=diff,e1)
local thresh = 0x7fff.ffff/(m/fps)
local e2 = "code is too large or slow -- try profiling manually with stat(1)"
assert(diff<=thresh,e2)
return diff*(m/fps)
end
local noop = function() end -- this must be local, because func is local
flip() --avoid flipping mid-measurement
local atot,asys=stat(1),stat(2)
for _=1,n do noop(unpack(locals)) end -- calibrate
local btot,bsys=stat(1),stat(2)
for _=1,n do func(unpack(locals)) end -- measure
local ctot,csys=stat(1),stat(2)
-- gather results
local tot=cycles(atot,btot,ctot)
local sys=cycles(asys,bsys,csys)
return {
lua=tot-sys,
sys=sys,
total=tot,
}
end
-->8
-- your code here
--edit me:
prof(function(dx,dy)
local d = max(abs(dx),abs(dy))
local n = min(abs(dx),abs(dy)) / d
return sqrt(n*n + 1) * d
end,function(dx, dy)
local d,n=abs(dx),abs(dy)
if (d<n) d,n=n,d
n/=d
return (n*n + 1)^0.5 * d
end,function(dx,dy)
local d,n=abs(dx),abs(dy)
if (d<n) d,n=n,d
n/=d
return sqrt(n*n + 1) * d
end,function(dx,dy)
local s = sin(atan2(dx,dy))
if (s==0) return abs(dx)
return abs(dy/s)
end,{ locals={3,4} })
-- "locals" (optional) are
-- passed in as args. see the
-- usage guide for details.
__label__
00006660000000006660000000006660000006006000606066600000066060600660060000000000000000000000000000000000000000000000000000000000
00006000060000006060666000006000000060006000606060600600600060606000006000000000000000000000000000000000000000000000000000000000
00006660666000006060000000006660000060006000606066606660666066606660006000000000000000000000000000000000000000000000000000000000
00000060060000006060666000000060000060006000606060600600006000600060006000000000000000000000000000000000000000000000000000000000
00006660000000006660000000006660000006006660066060600000660066606600060000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00006060000000006660000000006060000006006000606066600000066060600660060000000000000000000000000000000000000000000000000000000000
00006060060000006060666000006060000060006000606060600600600060606000006000000000000000000000000000000000000000000000000000000000
00006660666000006060000000006660000060006000606066606660666066606660006000000000000000000000000000000000000000000000000000000000
00000060060000006060666000000060000060006000606060600600006000600060006000000000000000000000000000000000000000000000000000000000
00000060000000006660000000000060000006006660066060600000660066606600060000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
70000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
07000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
07000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
70000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__sfx__
030100003052500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505

223
rearm_prototype.p8 Normal file
View File

@ -0,0 +1,223 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
-- vacuum gambit
-- by kistaro windrider
-- stdlib
-- generate standard "overlay"
-- constructor for type tt.
-- if tt.init is defined, generated
-- new calls tt.init(ret) after
-- ret is definitely not nil,
-- before calling setmetatable.
-- use to initialize mutables.
--
-- if there was a previous new,
-- it is invoked on the new
-- object *after* more, because
-- this works better with the
-- `more` impls i use.
function mknew(tt)
local mt,oldnew,more = {__index=tt},tt.new,rawget(tt, "init")
tt.new=function(ret)
if(not ret) ret = {}
if(more) more(ret)
if(oldnew) oldnew(ret)
setmetatable(ret, mt)
return ret
end
return tt
end
function easeoutbounce(t)
local n1=7.5625
local d1=2.75
if (t<1/d1) then
return n1*t*t;
elseif(t<2/d1) then
t-=1.5/d1
return n1*t*t+.75;
elseif(t<2.5/d1) then
t-=2.25/d1
return n1*t*t+.9375;
else
t-=2.625/d1
return n1*t*t+.984375;
end
end
-->8
-- entry points
function _draw()
cls()
draw_hud_placeholder()
left_pane:draw()
right_pane:draw()
rearm_pane_instance:draw()
end
function _init()
item=1
bfm=1
crt_frm = 1
left_pane = weapon_pane.new{}
right_pane = weapon_pane.new{
is_left=false,
s = 2,
hdr = "vulc",
body = " rate\n\n faster\n firing\n rate",
hot = function() return item == 2 end}
rearm_pane_instance = rearm_pane.new{hot=function() return item < 0 end}
end
function _update60()
crt_frm += 0.25
if (crt_frm >= 9) crt_frm = 1
if (btn(3) and item > 0 or btn(2) and item < 0) item = -item
if (btn(0)) item = 1
if (btn(1)) item = 2
if (btn() & 0xF ~= 0) and bfm >= 10 or bfm >= 30 then
bfm = 1
else
bfm += 1
end
if btnp(4) then
left_pane.pos = -1
right_pane.pos = -1
rearm_pane_instance.pos = -1
end
if btnp(5) then
left_pane.pos = 1
right_pane.pos = 1
rearm_pane_instance.pos = 1
end
left_pane:update()
right_pane:update()
rearm_pane_instance:update()
end
function draw_hud_placeholder()
rectfill(112, 0, 127, 127,0x56)
rect(112,0,127,127,7)
line(127,1,127,127,5)
line(113,127)
end
-->8
-- rearm pane drawing
crt={-91,-166,-2641,-1441,-23041,23295,-20491,24570}
function glow_box(x0, y0, x1, y1, c, cf)
for i,v in ipairs{c[1],c[2],c[1],0} do
i -= 1
rect(x0+i,y0+i,x1-i,y1-i,v)
end
fillp(crt[crt_frm&0xff])
rectfill(x0+4, y0+4, x1-4, y1-4, cf)
fillp()
end
function frame_col(hot)
if (not hot) return {4,10}
if (bfm<=16) return {14,7}
return {2,8}
end
function draw_weap_opt(x, y, c, s, hdr, body)
camera(-x,-y)
glow_box(0,0,55,100,c,1)
spr(s,5, 5)
print(hdr, 13, 8, 7)
print(body, 5, 15, 6)
camera()
end
function draw_rearm(c)
glow_box(0,101,111,127,c,1)
spr(5,15,107,4,2)
print("full ammo\nfull shield\n+50% health",54, 106, 6)
end
-->8
-- rearm pane objects
easing_pane = mknew{
-- to enter: pos = -1; to exit: pos = 1
-- runs for 32 frames in, 16 frames out
}
function easing_pane:frac()
local pos = self.pos
if (not pos) return
if (pos < 0) return 1-easeoutbounce(1+pos)
if (pos > 0) return (1-pos)*(1-pos)
return 0
end
function easing_pane:update()
local pos = self.pos
if (not pos or pos == 0) return
if (pos < 0) pos = min(pos + 0x0.05, 0)
if pos > 0 then
pos -= 0x0.1
if (pos <= 0) pos = nil
end
self.pos = pos
end
weapon_pane = mknew(easing_pane.new{
is_left = true,
s = 1,
hdr = "hull",
body = "\n +1\n max\n health",
hot = function() return item == 1 end,
})
function weapon_pane:draw()
local frac, is_left = self:frac(), self.is_left
if (not frac) return
camera(
frac * (is_left and 55 or -128) + (1-frac) * (is_left and 0 or -56),
0)
glow_box(0,0,55,100,frame_col(self:hot()),1)
spr(self.s,5, 5)
print(self.hdr, 13, 8, 7)
print(self.body, 5, 15, 6)
camera()
end
rearm_pane = mknew(easing_pane.new{})
function rearm_pane:draw()
local frac = self:frac()
if (not frac) return
camera(0, -28 * frac)
glow_box(0,101,111,127,frame_col(self:hot()),1)
spr(5,15,107,4,2)
print("full ammo\nfull shield\n+50% health",54, 106, 6)
camera()
end
__gfx__
000000000b00000000000a0007700770000aa0000444440004444444000000000000000000000000000000000000000000000000000000000000000000000000
00000000bba80880000008000aa00aa00a0880a0447777700477777a000000000000000000000000000000000000000000000000000000000000000000000000
007007000aaa28780a0000000990099008000080477aaa7a0477aaaa000000000000000000000000000000000000000000000000000000000000000000000000
0007000008a8887808000000099009900080080047a0047a047a0000000000000000000000000000000000000000000000000000000000000000000000000000
00007000088888820000a000088008800000000047a0447a047a0000000000000000000000000000000000000000000000000000000000000000000000000000
00700700008888200000800008800880a000000a47a4477a047a4440000000000000000000000000000000000000000000000000000000000000000000000000
000000000008820000a0000008800880080aa080477777a00477777a000000000000000000000000000000000000000000000000000000000000000000000000
0000000000002000008000000880088000088000477770000422aaaa222200020000020000000000000000000000000000000000000000000000000000000000
0d5000000000000000000000000000000000000047a77700022ee0002eeee002e00022e000000000000000000000000000000000000000000000000000000000
d00000000000000000000000000000000000000047a4777002ea2e002e002e02ee022ee000000000000000000000000000000000000000000000000000000000
500000000000000000000000000000000000000047a0477a22ea2e002e002e02e2e2e2e000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000047a0047a2e2222e02e222e02e02e02e000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000047a0047a2eeeeeea2eeee002e02e02e000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000aa000aa2e7aa2ea2e00e002e02e02e000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000002e0002e02e002e02e02e02e000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000e0000e00e000e00e00e00e000000000000000000000000000000000000000000000000000000000

File diff suppressed because it is too large Load Diff

598
zotprofiling.p8 Normal file
View File

@ -0,0 +1,598 @@
pico-8 cartridge // http://www.pico-8.com
version 42
__lua__
-- prof: cpu cycle counter v1.4
-- BY PANCELOR
--[[------------------------
use this cart to precisely
measure code execution time
--------------------------------
★ overview ★
--------------------------------
| tab 0 | usage guide |
| tab 1 | (internals) |
| tab 2 | your code here |
--------------------------------
-----------------------
-- ★ usage guide ★ --
-----------------------
웃: i have two code snippets;
which one is faster?
🐱: edit the last tab with your
snippets, then run the cart.
it will tell you precisely
how much cpu it takes to
run each snippet.
the results are also copied
to your clipboard.
웃: what do the numbers mean?
🐱: the cpu cost is reported
as lua and system cycle
counts. look up stat(1)
and stat(2) for more info.
if you're not sure, just
look at the first number.
lower is faster (better)
웃: why "{locals={9}}"
in the example?
🐱: accessing local variables
is faster than global vars.
so if your test involves
local variables, simulate
this by passing them in:
prof(function(a)
sqrt(a)
end,{ locals={9} })
/!\ /!\ /!\ /!\
local values from outside
the current scope are also
slower to access! example:
global = 4
local outer = 4
prof(function(x)
local _ = x --fast
end,function(x)
local _ = outer --slow
end,function(x)
local _ = global --slow
end,{ locals={4} })
/!\ /!\ /!\ /!\
웃: can i do "prof(myfunc)"?
🐱: no, this sometimes gives
wrong results! always use
inline functions:
prof(function()
--code for myfunc here
end)
as an example, "prof(sin)"
reports "-2" -- wrong! but
"prof(function()sin()end)"
correctly reports "4"
(see the technical notes at
the start of the next tab
for a brief explanation.
technically, "prof(myfunc)"
will work if myfunc was made
by the user, but you will
risk confusing yourself)
---------------
★ method 2 ★
---------------
this cart is based on
code by samhocevar:
https://www.lexaloffle.com/bbs/?pid=60198#p
if you do this method, be very
careful with local/global vars.
it's very easy to accidentally
measure the wrong thing.
here's an example of how to
measure cycles (ignoring this
cart and using the old method)
function _init()
local a=11.2 -- locals
local n=1024
flip()
local tot1,sys1=stat(1),stat(2)
for i=1,n do end --calibrate
local tot2,sys2=stat(1),stat(2)
for i=1,n do local _=sqrt(a) end --measure
local tot3,sys3=stat(1),stat(2)
function cyc(t0,t1,t2) return ((t2-t1)-(t1-t0))*128/n*256/stat(8)*256 end
local lua = cyc(tot1-sys1,tot2-sys2,tot3-sys3)
local sys = cyc(sys1,sys2,sys3)
print(lua.."+"..sys.."="..(lua+sys).." (lua+sys)")
end
run this once, see the results,
then change the "measure" line
to some other code you want
to measure.
note: wrapping the code inside
"_init()" is required, otherwise
builtin functions like "sin"
will be measured wrong.
(the reason is explained at
the start of the next tab)
---------------
★ method 3 ★
---------------
another way to measure cpu cost
is to run something like this:
function _draw()
cls(1)
local x=9
for i=1,1000 do
local a=sqrt(x) --snippet1
-- local b=x^0.5 --snippet2
end
end
while running, press ctrl-p to
see the performance monitor.
the middle number shows how much
of cpu is being used, as a
fraction. (0.60 = 60% used)
now, change the comments on the
two code snippets inside _draw()
and re-run. compare the new
result with the old to determine
which snippet is faster.
note: every loop iteration costs
an additional 2 cycles, so the
ratio of the two fractions will
not match the ratio of the
execution time of the snippets.
but this method can quickly tell
you which snippet is faster.
]]
-->8
--[[ profiler.lua
more info: https://www.lexaloffle.com/bbs/?tid=46117
usage:
prof(function()
memcpy(0,0x200,64)
end,function()
poke4(0,peek4(0x200,16))
end)
passing locals:
prof(
function(a,b)
local c=(a+1)*(b+1)-1
end,
function(a,b)
local c=a*b+a+b
end,
{locals={3,5}}
)
getting global/local variables exactly right
is very tricky; you should always use inline
functions like above; if you try e.g. prof(sin)
the results will be wrong.
# minutiae / notes to self:
---------------------------
doing this at top-level is awkward:
for _=1,n do end -- calibrate
for _=1,n do sin() end -- measure
b/c sin is secretly local at top-level,
so it gives a misleading result (3 cycles).
do it inside _init instead for a
more representative result (4 cycles).
## separate issue:
------------------
if you call prof(sin), it gives the wrong result (-2 cycles) because
it's comparing sin() against noop() (not truly nothing).
but we want the noop() there for normal inline prof() calls,
to avoid measuring the cost of the indirection
(calling func() from inside prof() is irrelevant to
how cpu-expensive func()'s body is)
]]
-- prof(fn1,fn2,...,fnN,[opts])
--
-- opts.locals: values to pass
-- opts.name: text label
-- opts.n: number of iterations
function prof(...)
cls()
local funcs={...}
local opts=type(funcs[#funcs])=="table" and deli(funcs) or {}
-- build output string
local msg=""
local function log(s)
msg..=s.."\n"
end
if opts.name then
log("prof: "..opts.name)
end
for fn in all(funcs) do
local dat=prof_one(fn,opts)
log(sub(" "..dat.total,-3)
.." ("
..dat.lua
.." lua, "
..dat.sys
.." sys)")
end
-- copy to clipboard
printh(msg,"@clip")
-- print + pause
while btn() == 0 do
flip()
end
color(6)
stop(msg)
end
function prof_one(func, opts)
opts = opts or {}
local n = opts.n or 0x200 --how many times to call func
local locals = opts.locals or {} --locals to pass func
-- we want to type
-- local m = 0x80_0000/n
-- but 8MHz is too large to fit in a pico-8 number,
-- so we do (0x80_0000>>16)/(n>>16) instead
-- (n is always an integer, so n>>16 won't lose any bits)
local m = 0x80/(n>>16)
assert(0x80/m << 16 == n, "n is too small") -- make sure m didn't overflow
local fps = stat(8)
-- given three timestamps (pre-calibration, middle, post-measurement),
-- calculate how many more CPU cycles func() took compared to noop()
-- derivation:
-- T := ((t2-t1)-(t1-t0))/n (frames)
-- this is the extra time for each func call, compared to noop
-- this is measured in #-of-frames -- it will be a small fraction for most ops
-- F := 1/30 (seconds/frame) (or 1/60 if this test is running at 60fps)
-- this is just the framerate that the tests run at, not the framerate of your game
-- M := 256*256*128 = 0x80_0000 = 8MHz (cycles/second)
-- (PICO-8 runs at 8MHz; see https://www.lexaloffle.com/dl/docs/pico-8_manual.html#CPU)
-- cycles := T frames * F seconds/frame * M cycles/second
-- optimization / working around pico-8's fixed point numbers:
-- T2 := T*n = (t2-t1)-(t1-t0)
-- M2 := M/n = (M>>16)/(n>>16) := m (e.g. when n is 0x1000, m is 0x800)
-- cycles := T2*M2*F
local function cycles(t0,t1,t2)
local diff = (t2-t1)-(t1-t0)
local e1 = "must use inline functions -- see usage guide"
assert(0<=diff,e1)
local thresh = 0x7fff.ffff/(m/fps)
local e2 = "code is too large or slow -- try profiling manually with stat(1)"
assert(diff<=thresh,e2)
return diff*(m/fps)
end
local noop = function() end -- this must be local, because func is local
flip() --avoid flipping mid-measurement
local atot,asys=stat(1),stat(2)
for _=1,n do noop(unpack(locals)) end -- calibrate
local btot,bsys=stat(1),stat(2)
for _=1,n do func(unpack(locals)) end -- measure
local ctot,csys=stat(1),stat(2)
-- gather results
local tot=cycles(atot,btot,ctot)
local sys=cycles(asys,bsys,csys)
return {
lua=tot-sys,
sys=sys,
total=tot,
}
end
-->8
-- your code here
--edit me:
function linefill(ax,ay,dx,dy,r,c)
if(c) color(c)
-- avoid overflow
-- credits: https://www.lexaloffle.com/bbs/?tid=28999
local d,n = abs(dx),abs(dy)
if (d<n) d,n=n,d
n/=d
d*=sqrt(n*n+1)
if(d<0.001) return
local ca,sa=dx/d,-dy/d
-- polygon points
local s={
{0,-r},{d,-r},{d,r},{0,r}
}
local u,v,spans=s[4][1],s[4][2],{}
local x0,y0=ax+u*ca+v*sa,ay-u*sa+v*ca
for i=1,4 do
local u,v=unpack(s[i])
local x1,y1=ax+u*ca+v*sa,ay-u*sa+v*ca
local _x1,_y1=x1,y1
if(y0>y1) x0,y0,x1,y1=x1,y1,x0,y0
local dx=(x1-x0)/(y1-y0)
if(y0<0) x0-=y0*dx y0=-1
local cy0=y0\1+1
-- sub-pix shift
x0+=(cy0-y0)*dx
for y=y0\1+1,min(y1\1,127) do
-- open span?
local span=spans[y]
if span then
rectfill(x0,y,span,y)
else
spans[y]=x0
end
x0+=dx
end
x0,y0=_x1,_y1
end
end
function quickzot(x,y,r,dx,dy,hot,warm,cold)
local x0, y0, r2 = x-dx, y-dy, r/2
rectfill(x0-0.5-r2, y0-0.5-r2, x0+r2+0.5, y0+r2+0.5, cold)
local a = atan2(dx,dy)-0.25
local tdx,tdy=cos(a), sin(a)
for i=-r*0.65,r*0.65,0.65 do
line(x0+i*tdx, y0+i*tdy, x+i*tdx, y+i*tdy, warm)
end
rectfill(x-r2,y-r2,x+r2,y+r2,hot)
end
function zot(x,y,r,dx,dy,hot,warm,cold)
local x0,y0,sdx,sdy=x-dx,y-dy,sgn(dx),sgn(dy)
local rx,ry=r*sdx,r*sdy
if cold then
rectfill(x0-rx,y0-ry,x0+rx,y0+ry,cold)
local sdxh,sdyh=sdx/2,sdy/2
line(x0-rx-sdxh,y0+ry+sdyh,x-rx,y+ry,cold)
line(x0+rx+sdxh,y0-ry-sdyh,x+rx,y-ry,cold)
end
for i=-r,r do
line(x0+i*sdx,y0-ry,x+rx,y-i*sdy,warm)
line(x0-rx,y0+i*sdy,x-i*sdx,y+ry,warm)
end
for i=-r,r do
line(x0,y0,x+rx,y-i*sdy,hot)
line(x0,y0,x-i*sdx,y+ry,hot)
end
end
function respr(x,y,dx,dy,r,s)
if (r==0) r=0.5
local n=ceil(max(abs(dx),abs(dy))/r/2)
local d1x,d1y=dx/n,dy/n
r/=4
for i=1,n do
spr(s,x,y,r,r)
x+=d1x
y+=d1y
end
pal()
spr(s,x,y,r,r)
end
darkpal = {
[7]=4,
[9]=2,
[10]=4,
[8]=2
}
prof(function(dx, dy, r)
linefill(32,32,dx,dy,r,10)
end,function(dx, dy, r)
quickzot(96,32,r,dx,dy,10,9,8)
end,function(dx,dy,r)
zot(32,96,r,dx,dy,10,9,8)
end,function(dx,dy,r)
pal(darkpal)
respr(96,96,dx,dy,r,r)
end,{ locals={4,-9,2} })
-- "locals" (optional) are
-- passed in as args. see the
-- usage guide for details.
__gfx__
a0000000aa0000000990000009999000009999000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000aa00000097a800009aaaa800097aaa900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000009aa800009a7aa8009777aaa80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000088000009aaaa8009a7aaaa80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000009aaaa8009aaaaaa80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000088880009aaaaaa80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000009aaaa800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000008888000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__label__
00006660000000006660000000006660000006006000606066600000066060600660060000000000000000000000000000000000000000000000000000000000
00006000060000006060666000006000000060006000606060600600600060606000006000000000000000000000000000000000000000000000000000000000
00006660666000006060000000006660000060006000606066606660666066606660006000000000000000000000000000000000000000000000000000000000
00000060060000006060666000000060000060006000606060600600006000600060006000000000000000000000000000000000000000000000000000000000
00006660000000006660000000006660000006006660066060600000660066606600060000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00006060000000006660000000006060000006006000606066600000066060600660060000000000000000000000000000000000000000000000000000000000
00006060060000006060666000006060000060006000606060600600600060606000006000000000000000000000000000000000000000000000000000000000
00006660666000006060000000006660000060006000606066606660666066606660006000000000000000000000000000000000000000000000000000000000
00000060060000006060666000000060000060006000606060600600006000600060006000000000000000000000000000000000000000000000000000000000
00000060000000006660000000000060000006006660066060600000660066606600060000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
70000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
07000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00700000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
07000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
70000000888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__sfx__
030100003052500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505005050050500505