Compare commits

..

19 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
5 changed files with 1573 additions and 0 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

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

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