extreme-tetrom/extreme-tetrom.p8

2445 lines
72 KiB
Plaintext
Raw Normal View History

pico-8 cartridge // http://www.pico-8.com
version 36
__lua__
--extreme tetrom
--by vanessa♥,kistaro,nyeogmi
version={7,4}
cartdata("extreme_tetrom_v7_0")
function usplit(str)
return unpack(split(str))
end
function csv(s)
local ret=split(s,"\n")
for i,v in ipairs(ret) do
ret[i] = type(v) == "string" and split(v) or {v} end
return ret
end
function _init()
for i=0,15 do
poke(0x5f60+i,i)
end
-- garbage color nybbles
garbage_bg=split"1,2,4,5,13"
garbage_fg=split"1536,1792,768,2584"
tetroms,start,do_update={all="ijlostz"},true,true
for i,t in ipairs(split"i,j,l,o,s,t,z") do
tetroms[t]=init_tetrom(15+i)
end
kick = split"0,0,-1,0,-1,-1,0,2,-1,2,0,0,-1,0,-1,1,0,-2,-1,-2,0,0,1,0,1,-1,0,2,1,2,0,0,1,0,1,1,0,-2,1,-2,0,0,1,0,1,-1,0,2,1,2,0,0,-1,0,-1,1,0,-2,-1,-2,0,0,-1,0,-1,-1,0,2,-1,2,0,0,1,0,1,1,0,-2,1,-2,0,0,-2,0,1,0,-2,1,1,-2,0,0,-2,0,1,0,1,2,-2,-1,0,0,-1,0,2,0,-1,2,2,-1,0,0,2,0,-1,0,2,1,-1,-1,0,0,2,0,-1,0,2,1,-1,-2,0,0,-2,0,1,0,-2,1,1,-1,0,0,1,0,-2,0,1,2,-2,-1,0,0,2,0,-1,0,-1,2,2,-1"
updaters={update_menu,update_options,update_scoremenu,update_game}
drawers={draw_menu,draw_options,draw_scoremenu,draw_game}
init_modes()
init_menu()
end
function _update60()
anim.update()
updaters[gstate]()
end
function _draw()
cls()
camera()
bg.draw()
drawers[gstate]()
anim.draw()
end
--helper functions, data
function confirm()
return btnp()&0x0030~=0
end
function confirm_delay()
if (not confirm_deadline) confirm_deadline=time()+1
if time()>=confirm_deadline and confirm() then
confirm_deadline=nil
return true
end
return false
end
function get_num(d,m,n)
return d%m^(n+1) \ m^n
end
function put_num(d,m,x)
return d*m+x
end
function bitpack(t)
local ret=0
for i=#t,1,-1 do
ret<<=1
if(t[i])ret+=1
end
return ret
end
function get_bit(num,n)
return 0!=num&2^n
end
function printc_multi(s,y,c,m)
local p,n = split(s," ")
for i,st in ipairs(p) do
st=tostr(st)
if not n then
n=st
elseif #st+#n+1 <= m then
n..=" "..st
else
printc(n,y,c)
y+=7
n=st
end
end
printc(n,y,c)
end
function print3(s,y,w)
for i=5,7 do
printc(s,y+7-i,i,w)
end
end
function cyclenum(n,low,up)
low=low or 1
up=up or low+1
return(n-low)%(up-low+1)+low
end
function fmttime(t)
return zpad(t\60,2)..":"..zpad(flr(t)%60,2)
end
function printc(s,y,c,w)
local ww = print(s,0,256)
print(s,64-ww\2,y,c)
end
function btoi(b)
return b and 1 or 0
end
function cpt(from,to)
for k,v in pairs(from) do
if type(v)=="table" then
to[k]=to[k]or{}
cpt(v,to[k])
else
to[k]=v
end end end
function get_sprite(n)
local bytes,addr={},n\16*512+n%16*4
for i=0,31 do
bytes[i+1]=peek(addr+i%4+i\4*64)
end
return bytes,fget(n)
end
function zpad(str,len)
local res=""
str=tostr(str)
for i=1,(len or 2)-#str do
res..="0"
end
return res..str
end
function irnd1(n)
return flr(rnd(n))+1
end
-->8
--globals, init
--beginner curve - vaguely reminicent of classic tetris
classic_level_curve=csv[[1000,0.001
999,0.2
850,0.2
849,0.25
800,0.25
799,0.33
750,0.33
749,0.5
700,0.5
699,0.75
650,0.75
649,1
600,1
599,2
550,2
549,3
500,3
499,4
450,4
449,5
400,5
399,6
350,6
349,8
300,8
299,10
250,10
249,12
200,12
199,16
150,16
149,22
100,22
99,30
50,30
49,60
0,60]]
-- section, are, line are, das delay, lock delay
classic_sections=csv[[50,4,0,3,10,10
45,5,1,4,10,5
44,6,1,5,10,5
43,6,2,5,10,5
42,8,4,6,10,5
41,8,4,6,11,5
40,8,4,6,12,5
38,8,4,6,13,5
35,8,4,6,14,5
30,8,4,6,15,5
29,8,4,6,17,4
28,8,4,6,20,4
27,8,4,6,24,4
26,10,6,6,24,3
25,10,6,8,30,3
24,12,8,10,30,3
23,12,10,10,30,2
22,15,10,12,30,2
21,15,15,12,30,2
11,20,20,15,30,1
6,25,20,15,30,1
1,30,20,15,30,1]]
function init_tetrom(num)
local t,bytes,flags={pattern={}},get_sprite(num)
for a=1,4 do
add(t.pattern,{{},{},{},{}})
end
for i=1,32 do
local left,right,clm,tpat=bytes[i]%16,bytes[i]\16,(2*i-1)%4,t.pattern[ceil(((i-1)%4+1)/2)+2*btoi(16<i)][4-((ceil(i/4)-1)%4)]
if(0!=left)tpat[clm]=left
if(0!=right)tpat[clm+1]=right
end
t.color=((flags&0x0f)<<8)+((flags&0xf0)>>4)
return t
end
function init_matrix(rows,clms)
local mtx={}
for r=1,rows do
mtx[r]={}
for c=1,clms do
mtx[r][c]=0
end end
return mtx
end
function initwnd(x,y,w,h,m)
local win={
x=x,y=y,w=w,h=h,matrix=m}
return win
end
-- block outline color flash
-- animates last-to-first!
-- first value is normal outline color
stdflash=split"135,138,11,12,13,141,2,14,142,15,7"
dkflash=split"13,141,133,130,129,1,131,134,6,6,7,7"
ltflash=split"0,128,129,1,3,139,138,135,10,7,135,7"
function init_game(gamev)
gstate,messages,endgame,dirty=4,{},false,true
tetromsfx={i=8,o=9,t=7,j=6,l=5,s=3,z=4}
--windows
field=initwnd(33,3,10,20,init_matrix(40,10))
hold=initwnd(usplit"2,14,4,4")
preview=initwnd(usplit"100,14,4,4")
bg.set"grid"
bufmtx=init_matrix(40,10)
--delay after locking
arecnt,arelen,areuse,clearing=0,10,false,false
--delayed auto shift
--delay vars, not used for drop
das_len,das_cnt=14,0
--done=false
das_bh=0 --last button held
--the globals formerly known as game{}
score=0
lines=0
linesneeded=150
level=1
drops=0
gametime=0
gm_glv=0
gm_gtm=0
gm_progress=0
--higher is better,this inverses that
invscr_ordering=false
-- T-twist adds 2 tiers.
-- so "5 lines" is actually a T-twist triple
pts=split"10,30,50,80,150"
sprite={
normal=1,
active=2,
hold=1,
ghost=1,
preview=1
}
gridspr=0
progbar=true
bganim=true
combo=0
maxcombo=0
streaking=false
invisible=false
outline_only=false
invrot=false
flash_idx=1
flashies={}
flash_on_lock=true -- otherwise, swoosh only
--game is over if true
topout=false
justended=false
lv={
tets=0,
progress=0,
goal=50,
--how much progess per
--line clear; affected by t-twists
vals=split"1,3,5,8,12"
}
bags=1
level_curve={}
sections={}
clrspd=1
--stats shown on the left
--bottom-to-top
stats={}
--how many pieces in preview
--prevlen=6 --inlined
spawn={3,18}
--frames spent per row
gravity=0
gravcnt=0
--extra frames of are after
--line clear
lnclr_delay=10
--when on floor, how many
--frames before locking
lockdelay=30
lockcnt=0
locking_harddrop=true
--tetromino sequence
seq={}
ghost={
y=0,draw=true,
color=0xd01
}
--{name,orientation,x,y}
curtet={}
hldtet={"",1}
holdused=false
qualify = yes
on_level = nil
on_drop = nil
--load mode+options
cpt(gamev,_ENV)
-- nonmerging defaults
if (#level_curve == 0) cpt(classic_level_curve, level_curve)
if (#sections == 0) cpt(classic_sections, sections)
if (#flashies == 0) cpt(stdflash, flashies)
gm_values, gm_decay_cap=calc_gm_values(0)
gm_landmark=deli(level_curve)
next_gm_landmark=deli(level_curve)
nextsec=deli(sections)
level_changes(level)
calc_grav()
hiscore=getscore(getscores(mode)[1],true)
randomize_bag()
last_hole = irnd1(10)
while not curtet[1] or not del(split"i,t,j,l",curtet[1]) do next_tetrom(true) end
menuitem(1,"retry",function()
init_game(gamev)
end)
menuitem(2,"back to title",init_menu)
poke(0x5f5c,0xff) --disable btnp repeat
end
-->8
--update routines, game logic
function das_delay()
if das_done or das_cnt>=das_len then
das_done=true
else
das_cnt+=1
end
if das_stuck then
das_stuck=false
return true
end
return das_done
end
function do_das()
local x,y=0,0
local bh,bv=
btoi(btn"1")-btoi(btn"0"),
btn"3"
--horizontal
if bh==0 or das_bh!=bh then
x,das_cnt,das_stuck,das_done=bh,0
elseif das_delay() then
x=bh
end
--vertical
if (bv) y-=1
das_bh=bh
return x,y
end
function do_kick(iscw)
local ct=curtet
--choosing the right tests
local ix=
("i"==ct[1] and 80 or 0)+
(iscw and 0 or 40)+
(ct[2]-1)*10
--kick string format:
--160 chars = [80 chars sztjl kicks][80 chars i kicks]
--80 chars = [40 chars clockwise][40 chars counterclockwise]
--40 chars = [10 chars orientation 1][...orientaiton 2][...3][...4]
--10 chars = [kick 1, x + 2][kick 1, y + 2] - repeat 5 times total for 5
-- note: orientation is destination, not source
--do tests
for i=ix+1,ix+9,2 do
local kx,ky=kick[i],kick[i+1]
if (move(kx,ky)) then
-- do not permit kicks to pop back up
if kx|ky~=0 then
while ct[4] > ct[5] and mv_vt(-1) do end
end
return true
end
end
return false
end
function legal(t)
local m=field.matrix
for row=1,4 do
for clm=1,4 do
--current block
local b=tetroms[t[1]].pattern[t[2]][row][clm]
if(b)then
local x,y=clm+t[3],row+t[4]
if(1>x or #m[1]<x or 1>y or #m<y or 0!=m[y][x])return false
end
end end
return true
end
function mv_vt(dist)
if(0==dist)return true
curtet[4]+=dist
--undo if illegal
if(not legal(curtet))then
curtet[4]-=dist
return false
end
--reset counters
update_floor()
gravcnt=0
update_ghost()
sfx"12"
return true
end
function mv_hz(dist)
if(0==dist)return
curtet[3]+=dist
if(not legal(curtet))then
curtet[3]-=dist
das_stuck=true
return
end
update_ghost()
sfx"13"
end
function move(dx,dy)
curtet[3]+=dx
curtet[4]+=dy
if(not legal(curtet))then
curtet[3]-=dx
curtet[4]-=dy
return false
end
update_ghost()
return true
end
function rotate_curtet(iscw)
local ct = curtet
local temp=ct[2]
if (not iscw) ct[2]-=2
ct[2]%=4
ct[2]+=1
--wallkick
if not do_kick(iscw) then
ct[2]=temp
sfx"0"
return false
end
--t-twists
ttwist=false
if ct[1] == "t" then
local n,mx,x,y=0,field.matrix,ct[3]+1,ct[4]+2
local my = mx[y]
if (not my or my[x]~=0) n+=1
if (not my or my[x+2]~=0)n+=1
my = mx[y+2]
if (not my or my[x]~=0) n+=1
if (not my or my[x+2]~=0)n+=1
ttwist=n>2
end
update_ghost()
sfx(btoi(iscw)+(ttwist and 30 or 1))
return true
end
function tryfall()
if (ghost.y==curtet[4]) return false
curtet[4]-=1
update_floor()
sfx"12"
return true
end
function update_floor()
local ct = curtet
if ct[4] < ct[5] then
ct[5] = ct[4]
lockcnt = 0
end
end
function update_ghost()
local t={}
cpt(curtet,t)
--try moving down
while legal(t) do
t[4]-=1
end
--illegal, undo last move
t[4]+=1
--move ghost
ghost.y=t[4]
end
function rnd_row(r,h)
local mr={}
field.matrix[r] = mr
for i=1,10 do
mr[i]=rnd(garbage_bg)+rnd(garbage_fg)
end
mr[h]=0
end
lockfade = split"7,6,134,5,133,128"
function counters()
gametime+=1/60
if(gm_decay_cap)gm_progress=max(gm_progress-1/gm_decay_cap,0)
--are, spawning tetromino
if areuse then
if arecnt>=arelen then
next_tetrom()
sfx(tetromsfx[seq[1]])
if (not clearing) areuse,arecnt=false,0
else
arecnt+=1
end
else
--gravity
calc_grav()
if ghost.y<curtet[4] and not areuse then
local g=gravity
gravcnt+=1
while gravcnt>=g do
if not tryfall() then
gravcnt=0
break
end
gravcnt=max(0,gravcnt-g)
end
end
--lock delay
if ghost.y>=curtet[4] then
if lockcnt>=lockdelay then
lockdn(false)
lockcnt=0
else
lockcnt+=1
end
end
-- lock fade
if not(outline_only or invisible) and lockcnt > 0 then
pal(15, lockfade[lockcnt*6\lockdelay+1], 1)
end
end end
function update_game()
pal(15,flashies[flash_idx],1)
if (flash_idx>1) flash_idx -= 1
if(not do_update)return
update_msgs() --tab 9
if not topout then
btn_handler()
counters()
if over() then
topout=true
justended=true
end end
if topout then
if justended then
rank = qualify() and addscore(mode,getscore()) or -1
justended=false
end
--reset game
if (confirm_delay()) init_menu()
end
end
function btn_handler()
local x,y=do_das()
if (areuse) return
mv_hz(x)
if(not mv_vt(y) and not locking_harddrop)lockdn()
--hard drop,hold
if not held_since_harddrop and btn()&0x7==0x4 then
held_since_harddrop = true
hard_drop()
return
end
held_since_harddrop = held_since_harddrop and btn"2"
if btn()&0x30==0x30 then
swap_hold()
else
--rotation
local bp=btnp()&0x30
if(bp~=0)rotate_curtet(bp==(invrot and 0x20 or 0x10))
end
end
function level_changes(n)
level_time=gametime
if (on_level and on_level(n)) return
if(0==n%4)bg.set("grid",{col=n\4})
if (5<=n)ghost.draw=false
while nextsec and nextsec[1] <= n do
_, arelen, lnclr_delay, das_len, lockdelay, clrspd = unpack(nextsec)
nextsec=deli(sections)
end
end
function gm_lv()
return lv.progress+(level-1)*lv.goal
end
--gravity in frames per row
function calc_grav()
if (not next_gm_landmark) return
local lv=gm_lv()
while next_gm_landmark[1]<=lv do
gm_landmark = next_gm_landmark
next_gm_landmark=deli(level_curve)
if not next_gm_landmark then
gm_gtm=gametime
gravity=gm_landmark[2]
return
end
end
local lvbase,lvnext=gm_landmark[1],next_gm_landmark[1]
--interpolate for current level
gravity=((lv-lvbase)*next_gm_landmark[2]+(lvnext-lv)*gm_landmark[2])/(lvnext-lvbase)
end
function randomize_bag()
local s=seq
local tet,from = tetroms.all,#s+1
for i=2,bags do tet..=tetroms.all end
local cs=split(tet,"")
while #cs>0 do
local c=rnd(cs)
add(s,c)
del(cs,c)
end
for _=1,3 do
for i=from,#s do
local t=s[i]
if t==s[i-1] or t==s[i-2] or t==s[i-3] then
if i<#s then
s[i],s[i+1]=s[i+1],t
else
s[i],s[from]=s[from],t
end
end
end
end
end
function next_tetrom(first)
ttwist=false
local ltr=deli(seq,1)
curtet=
--name,orientation,x,y,floor
{ltr,1,spawn[1], spawn[2], spawn[2]}
if not first then
if btn()&0x30==0x30 then
swap_hold()
else
--rotation
local b,bp=invrot and 0x20 or 0x10,btn()&0x30
if(bp!=0)rotate_curtet(bp==b)
end end
--updating sequence
--prevlen inlined
if 6>=#seq then
randomize_bag()
end
--block out
if not legal(curtet)then
topout=true
justended=true
return
end
--move 1 line down if possible
mv_vt(-1)
update_ghost()
end
function update_lines(morelines)
if(0==morelines)return
local glv=lv
lines+=morelines
glv.progress+=glv.vals[morelines]
if(morelines>=4 or ttwist)glv.tets+=1
--update level
if glv.progress>=glv.goal then
sfx"21"
level+=1
glv.progress-=glv.goal
gm_eligible=gm_eligible and glv.tets>=2
glv.tets=0
level_changes(level)
end
end
function update_scores(morelines)
if 1>morelines then
combo=0
return
end
local streakmul=1
if ttwist or morelines==4 then
if streaking then
streakmul=1.5
push_flatmsg(split"12,6,7,6,12,1","streak",usplit"105,85,5,30,2.5")
end
streaking=true
else
streaking=false
end
if (ttwist) morelines+=2
combo += 1
local lcombo = combo
if lcombo > 1 then
local cols,msg = split"3,11,7,11","combo\n "..tostr(lcombo)
if (lcombo > max(4, maxcombo)) cols,msg=split"2,8,9,10,9,8",msg.."!"
push_flatmsg(cols,msg,usplit"105,82,2,30,3")
end
maxcombo=max(lcombo,maxcombo)
if (getscore == scr_gm) gm_progress += gm_values[morelines]*gm_combo_value[morelines][min(combo,15)]*ceil(level/2)*streakmul
if gm_progress >= 120 then
gm_progress=0
local newlv,prev,_=gm_glv+1,parse_gm_ordinal(gm_ordinal())
gm_glv=newlv
local ngm,_=parse_gm_ordinal(gm_ordinal())
if(prev~=ngm) then
gm_gtm=gametime
if (newlv <= 25) sfx"24"
end
gm_values, gm_decay_cap=calc_gm_values(newlv)
end
score+=pts[morelines]*(1+(level-1)/10)*streakmul*(1.1^(combo-1))>>>16
--lines, process, level
update_lines(morelines)
--sfx
if 0!=morelines then
if 1>=combo then
sfx(13+morelines)
else sfx(16+min(4,combo))
end end
end
function check_rows()
local counter=0
local m=field.matrix
local row,arr=1,{}
while row<=#m do
--find out if full
local full=true
for clm=1,10 do
if 0==m[row][clm] then
full=false
break
end end
if full then
if(0==counter)cpt(m,bufmtx)
counter+=1
--anim
local x,y=34,124-6*(row+counter-1)
for i=0,9 do
local tmi=10-i
anim.new("crush",{x=x+6*i,y=y,c=m[row][i+1],lag=(100-tmi*tmi)/clrspd/10})
end
anim.new("swoosh",{x=x,y=y,age=0})
--delete row
deli(field.matrix,row)
--add empty row
local new={}
for i=1,10 do new[i]=0 end
add(field.matrix,new)
else--not full
row+=1
end end
return counter
end
function swap_hold()
if (holdused) return
local h,gs=hldtet,spawn
h[1],h[2],curtet=curtet[1],1,{h[1],h[2],gs[1],gs[2],gs[2]}
if ""==curtet[1] then
next_tetrom(true)
sfx(tetromsfx[curtet[1]])
else
--move 1 line down if possible
mv_vt(-1)
end
update_ghost()
holdused = true
sfx"22"
end
quadclr = split"7,10,4,5,1"
ttclrs=csv[[14,13,2,5,1
7,14,8,2,5,1
2,13,14,10,14,2,1
14,13,12,13,14,13,2,1]]
ttlabels=split"tWISt,tWISt\n SolO,tWISt\n DuO,tWISt\n trio"
function lockdn(hard)
dirty=true
gravcnt=0
if (flash_on_lock) flash_idx=#flashies
local t=curtet
for row=1,4 do
for clm=1,4 do
local lockout = true
--current block
local b=tetroms[t[1]].pattern[t[2]][row][clm]
if b then
--copying block to
--according pos in matrix
local x=clm+t[3]
local y=row+t[4]
field.matrix[y][x]=tetroms[t[1]].color
--at least one block
--locked in visible
--area, all ok!
if(20>y)lockout=false
end end end
if lockout then
topout=true
justended=true
return
end
drops+=1
--reset counters for next tetrom
gravcnt,lockcnt=0,0
--check rows, award points
local rcnt=check_rows()
update_scores(rcnt)
if (rcnt==4) push_flatmsg(quadclr,usplit"quad,105,85,6,30,2")
if ttwist then
local clrs=ttclrs[rcnt+1]
push_flatmsg(clrs,ttlabels[rcnt+1],102,80,5,5*#clrs,1.5)
end
areuse=true
arecnt=0
if(0!=rcnt)arecnt=-lnclr_delay
sfx(hard and 11 or 10)
holdused=false
if(lv.progress%lv.goal+1<lv.goal)lv.progress+=1
if (on_drop) on_drop()
end
function push_stack(l)
local m=field.matrix
for i=#m,l+1,-1 do
m[i]=m[i-1]
end
m[l]={}
if (rnd() <= 0.25) last_hole = irnd1(10)
rnd_row(l, last_hole)
update_ghost()
end
-- get a function that calls
-- push_stack(g) every n calls
-- g's default = 1
function garbage_every(n, g)
g = g or 1
local x = 0
return function()
x+=1
if x>=n then
push_stack(1)
x = 0
end
end
end
function hard_drop()
--just to make sure
update_ghost()
--drop and decay
curtet[4]=ghost.y
if locking_harddrop then
lockdn(true)
end end
-->8
--drawing routines
--draws an entire tetromino
function draw_tetrom(t,p,w,x,y,is_ghost)
local gg,gs=ghost,sprite
if(not gg.draw and is_ghost or not t)return
local s,c=is_ghost and gs.ghost or gs.active,is_ghost and gg.color or t.color
if w==hold then
s=gs.hold
if (holdused) fillp(▒\1|0b.11)
elseif w==preview then
s=gs.preview
end
--iterate over all blocks
for row=1,4 do
for clm=1,4 do
--any value means block exists
if t.pattern[p][row][clm] then
local xw,yw=clm+x,row+y
if(xw>0 and xw<=w.w and yw>0 and yw<=w.h) then
poke2(0x5f06,c)
spr(s,w.x-5+6*xw,w.y+1+6*(w.h-yw),0.75,0.75)
end
end
end end
poke2(0x5f06,0x706)
fillp()
end
--3*3 px per block
function mini_tetrom(ltr,x,y,s)
local t=tetroms[ltr]
local c=t.color
for row=1,4 do
for clm=1,4 do
if t.pattern[1][row][clm] then
local xpos,ypos=x+3*(clm-1),y+3*(4-(row-1))
s=s or sprite.preview
poke2(0x5f06,c)
sspr(8*s,0,6,6,xpos,ypos,3,3)
end
end
end
poke2(0x5f06,0x706)
end
--row-off,col-off;line-draw
borders=csv[[0,5,5,5,15,-11
0,0,0,5,15,-1
5,0,5,5,15,1
0,0,5,0,15,11]]
corners=csv[[0,5,15,-12
5,5,15,-10
0,0,15,10
5,0,15,12]]
function draw_window(w,b,bgc)
local cornerx,cornery=w.x+1+6*w.w,w.y+1+6*w.h
if bgc then
rectfill(w.x,w.y,cornerx,cornery,bgc)
if ghost.draw and not outline_only then
for clm=9,0,-1 do
for row=0,19 do
spr(23+gridspr,w.x+6*clm,w.y+6*row)
end end end end
--borders
if b then
for i=0,2 do
rect(w.x-i,w.y-i,cornerx+i,cornery+i,7-i)
end
if progbar then
local h=(6*w.h+6)*(lv.progress/lv.goal)
clip(w.x-2,cornery+4-h,6*w.w+6,h)
for i=0,2 do
rect(w.x-i,w.y-i,cornerx+i,cornery+i,
progcols[
min(4,level\5)*3+i+1
]
)
end
clip()
end end
--matrix
if(btn(6)) return --hide if pausing
if (not w.matrix or invisible and not topout) return
if not dirty then
palt(0,false)
sspr(0,64,60,62,w.x,w.y)
sspr(64,64,60,62,w.x,w.y+60)
palt(0,true)
return
end
local m=clearing and bufmtx or w.matrix
-- use cart ram as temporary matrix storage
-- speeds up border drawing enough to be worth it
memset(0x8000,1,11)
memset(0x800c,0,250)
for row,rr in ipairs(m) do
local ix=0x8000+row*11
poke(ix,1)
for clm,cc in ipairs(rr) do
if cc ~= 0 then
-- draw_block inlined
if not outline_only then
poke2(0x5f06,cc)
spr(sprite.normal,w.x-5+6*clm,w.y+1+6*(w.h-row),0.75,0.75)
end
poke(ix+clm,cc)
end end end
poke2(0x5f06,0x706)
-- block outlines; suppress if
-- outline color is 0, so users
-- can't peek at the well
-- by pausing
if (flashies[flash_idx]==0) return
local cpos = $0x5f28 --camera offsets
for row,rr in ipairs(m) do
local ir=0x8000+row*11
for clm,cc in ipairs(rr) do
local ix=ir+clm
if 0!=cc then
poke4(0x5f28,
cpos-w.y-6*(w.h-row)
-((w.x-5+6*clm)>>16))
for packed in all(borders) do
if 0==@(ix+packed[6]) then
line(unpack(packed))
end
end
for packed in all(corners) do
if 0==@(ix+packed[4]) then
pset(unpack(packed))
end
end
end
end end
poke4(0x5f28, cpos)
--save well to bottom half of sprite sheet
--draw mode: from screen to sprite sheet
poke2(0x5f54, 0x0060)
palt(0, false)
sspr(w.x,w.y,60,62,0,64)
sspr(w.x,w.y+60,60,62,64,64)
palt(0, true)
poke2(0x5f54,0x6000)
dirty = false
end
function draw_stats()
for i,s in ipairs(stats) do
local c=""
print(s,3,127-17*i,6)
local cl = 7
if s=="score" then c=scr(score,true)
elseif s=="time" then c=fmttime(gametime)
elseif s=="left" then
local rmn = linesneeded-lines
if (rmn <= linesneeded\4)cl=10
c=max(0,linesneeded-lines)
elseif s=="combo" then c=maxcombo
elseif s=="grade" then c,cl=gm_grade()
elseif s=="level" then
local glv,ggl=gm_lv(),level*lv.goal
if(glv==ggl-1)cl=9
if(ggl>999) ggl="⁘"
if(over==leveling_over and over()) ggl = "■"
c=tostr(glv).."/"..tostr(ggl)
elseif s =="section" then c=level
elseif s =="cpu" then
c=stat(1)*100\1
if (c>85)cl=9
if (c>100)cl=8
elseif s =="remain" then
c=drop_target-drops
if (c<10)cl=9
else c=_ENV[s] or "" end
print(c,31-print(c,1,-50),134-17*i,cl)
end end
function draw_game()
print("hold",3,5,6)
draw_window(hold)
draw_tetrom(tetroms[hldtet[1]],hldtet[2],hold,0,0)
print("❎+🅾️",5,30,5)
print("next",101,5,6)
draw_window(preview)
local t=seq[1]
draw_tetrom(tetroms[t],1,preview,0,0)
for i=2,6 do --prevlen inlined
mini_tetrom(seq[i],101,27+8*(i-2))
end
print("best",101,110,6)
print(hiscore,101,117,7)
draw_window(field,true,0)
local ct=curtet
if not areuse then
draw_tetrom(tetroms[ct[1]],ct[2],field,ct[3],ghost.y,true)
draw_tetrom(tetroms[ct[1]],ct[2],field,ct[3],ct[4])
end
draw_stats()
if topout then
if rank>=0 then
rectfill(usplit"34,59,93,72,7")
if rank > 3 then
if over() then
printc("clear!",60,11)
else
printc("game over",60,8)
end
elseif rank > 1 then
printc("high score "..rank,60,12)
else
printc("new record!",60,9)
end
printc(getscore(nil,true,1),67,0)
else
rectfill(usplit"34,59,93,65,7")
print(usplit"game over,46,60,8")
end
else
draw_msgs() --tab 9
end end
-->8
--menu
function init_menu()
poke(0x5f5c,0) --restore btnp repeat
menuitem(2)
menuitem(1)
bg.set("falling")
gstate=1
gamev,mode,slc={sprite={}},mode or 1,1
options=options or {
gamev={},
sprv={}
}
local spr_max=15
--titles between option items
opt_titles={[7]="tetromino sprites"}
--items in option menu
opt_strs=opt_strs or {
{name="locking hard drop",
curr=true,
set=function(self)
options.gamev.locking_harddrop=self.curr
end},
{name="inverse rotation",
curr=false,
set=function(self)
options.gamev.invrot=self.curr
end},
{name="progress bar",
curr=true,set=function(self)
options.gamev.progbar=self.curr
end},
{name="animated bg",
curr=true,set=function(self)
options.gamev.bganim=self.curr
end},
{name="debris",
curr=1,
vals=split"lots,some,none",
set=function(self)
if(self.curr<1)self.curr=1
options.gamev.debris=self.curr
end},
{name="well background",
curr=0,min=0,max=8,set=function(self)
options.gamev.gridspr=self.curr
end},
{name="normal",
curr=1,min=0,max=spr_max,
set=function(self)
options.sprv.normal=self.curr
end},
{name="active",
curr=2,min=0,max=spr_max,
set=function(self)
options.sprv.active=self.curr
end},
{name="ghost",
curr=1,min=0,max=spr_max,
set=function(self)
options.sprv.ghost=self.curr
end},
{name="hold",
curr=1,min=0,max=spr_max,
set=function(self)
options.sprv.hold=self.curr
end},
{name="preview",
curr=1,min=0,max=spr_max,
set=function(self)
options.sprv.preview=self.curr
end}}
if(start)readdata()
start=false
foreach(opt_strs, function(o) o:set() end)
if options then
cpt(options.gamev,gamev)
cpt(options.sprv,gamev.sprite)
writedata()
end
end
function update_menu()
if(not do_update)return
if btnp"2"then
slc=cyclenum(slc-1,1,4)
sfx"12"
end
if btnp"3"then
slc=cyclenum(slc+1,1,4)
sfx"12"
end
--start game
if 1==slc then
if confirm()then
cpt(modes[modes.list[mode]],gamev)
init_game(gamev)
end
--mode selection
elseif 2==slc then
if btnp"0"then
sfx"13"
mode-=1
if(0==mode)mode=#modes.list
elseif btnp"1"then
sfx"13"
mode%=#modes.list
mode+=1
end
--option menu
elseif 3==slc and confirm()then
init_options()
--highscore menu
elseif 4==slc and confirm()then
init_scoremenu()
end end
function draw_menu()
--border
for i=0,2 do
rect(i,i,127-i,127-i,5+i)
end
print3("extreme",18)
print(version[1].."."..version[2],4,119,5)
--logo
map(0,0,21,27,11,3)
printc("start!",65,btoi(1==slc)+6)
local m=modes.list[mode]
local s="mode: "..m
if(2==slc)s="⬅️ "..s.." ➡️"
printc(s,72,btoi(2==slc)+6,2*btoi(2==slc))
printc("options",79,btoi(3==slc)+6)
if (2==slc) then
printc_multi(modes[m].desc,100,5,27)
end
printc("high scores",86,btoi(4==slc)+6)
end
function init_options()
gstate,opt_slc=2,1
end
function update_options()
if(not do_update)return
if btnp"2"then
sfx"12"
opt_slc=cyclenum(opt_slc-1,1,#opt_strs+1)
end
if btnp"3"then
sfx"12"
opt_slc=cyclenum(opt_slc+1,1,#opt_strs+1)
end
--an option is selected
if opt_slc<=#opt_strs then
local o=opt_strs[opt_slc]
--what to do when
--⬅️ or ➡️ pressed
if(btnp"0"or btnp"1") then
sfx"13"
if "boolean"==type(o.curr)then
o.curr=not o.curr
else
local minv=o.min or 1
local maxv=o.max or#o.vals
if(btnp"0")o.curr=cyclenum(o.curr-1,minv,maxv)
if(btnp"1")o.curr=cyclenum(o.curr+1,minv,maxv)
end end
--back to title is selected
else
--❎/🅾️ confirm
if confirm() then
--set all options
foreach(opt_strs, function(o) o:set() end)
--switch to title menu
init_menu()
end end end
function draw_options()
cls()
for i=0,2 do
rect(i,i,127-i,127-i,5+i)
end
print3("options",4)
--tetroms at the bottom
for i=1,3 do
local os = opt_strs[6+i]
drawt(os.curr,5,45+20*i,os.name)
end
for i=1,2 do
local os = opt_strs[9+i]
drawt(os.curr,105,65+20*i,os.name,true)
end
mini_tetrom("t",100,100,opt_strs[11].curr)
--options
local x=6
for i=1,#opt_strs do
local o=opt_strs[i]
local s=o.name..": "
x+=6
if opt_titles[i] then
print3(opt_titles[i],x+2)
x+=10
end
if o.vals then
s=s..o.vals[o.curr]
elseif"boolean"==type(o.curr) then
s=s..(o.curr and"yes"or"no")
else
s=s..o.curr
end
if(opt_slc==i)s="⬅️ "..s.." ➡️"
printc(s,x,btoi(opt_slc==i)+6,2*btoi(opt_slc==i))
end
x+=7
printc("back to title",x,btoi(opt_slc==#opt_strs+1)+6)
end
function drawt(s,x,y,name,r)
poke2(0x5f06,0xe08)
if (name=="ghost"and opt_strs[5].curr) poke2(0x5f06,0xd01)
for i=0,12,6 do
spr(s,x+i,y+6)
end
spr(s,x+6,y)
poke2(0x5f06,0x706)
if name then
if(r)x-=max(0,4*#name-1)-18
print(name,x,y+13,5)
end end
function init_scoremenu()
opt_slc,gstate=1,3
highscores=getscores(mode)
end
function update_scoremenu()
if(not do_update)return
if btnp"2"then
sfx"12"
opt_slc=cyclenum(opt_slc-1,1,3)
end
if btnp"3"then
sfx"12"
opt_slc=cyclenum(opt_slc+1,1,3)
end
local temp=mode
if 1==opt_slc then
bp = btnp()&0x3
if bp~=0 then
sfx"13"
mode=cyclenum(mode+2*bp-3,1,#modes.list)
end
elseif 2==opt_slc then
if confirm()then
for i=10,63 do dset(i,0)end
sfx"23"
highscores=nil
end
else
if confirm()then
init_menu()
end
end
if (not highscores or temp!=mode) highscores=getscores(mode)
end
function draw_scoremenu()
cls()
rect(usplit"0,0, 127,127, 5")
rect(usplit"1,1, 126,126, 6")
rect(usplit"2,2, 125,125, 7")
print3("scores",6)
s=modes.list[mode]
if(opt_slc==1)s="⬅️ "..s.." ➡️"
local b1 = btoi(opt_slc==1)
printc(s,20,b1+6,2*b1)
printc("reset scores",27,btoi(opt_slc==2)+6)
printc("back to title",34,btoi(opt_slc==3)+6)
for i,s in ipairs(highscores) do
spr(32+i,41,19+25*i,1,2)
local m=modes[modes.list[mode]].getscore
printc(m(s,true,2),32+25*i,7)
end end
-->8
--modes
function scr(s,b,l)
s = s or score
if (l) return tostr(s,0x2)
if (not b) return s
local ret = tostr(s,0x2)
if (#ret > 5) return sub(ret,1,-4)..("K")
return zpad(ret,5)
end
function scr_t(s,b)
return b and fmttime(s or gametime) or s or gametime
end
function scr_l(s)
return s or lines
end
function scr_gm(s,disp,final)
s = s or 0x7ff0-gm_ordinal(not next_gm_landmark)+0x0.000a*min(0x1999, gm_gtm)
if(s==0) return disp and "---" or 0
local rank=-(flr(s)-0x7ff0)
if(final==1)return parse_gm_ordinal(rank,true)
return disp and parse_gm_ordinal(rank,final).."\n"..fmttime(s%1/0x0.000a) or s
end
function gm_nz()
return gm_glv ~= 0
end
function scr_lvltime(s, disp,final)
s = s or 0x7ff0-level+0x0.000a*min(0x1999,level_time)
if (not disp) return s
if (s == 0) return "---"
return tostr(-(flr(s)-0x7ff0))..(final and "@" or "\n")..fmttime(s%1/0x0.000a) or s
end
function sec_nz()
return level ~= 0
end
function lines_over() return lines>=linesneeded end
function leveling_over() return not next_gm_landmark end
function darken(flash)
outline_only=true
flashies=flash
flash_idx=#flash
end
function drops_over()
return drops>=drop_target
end
function yes() return true end
function no() end
function init_modes()
modes={
list=split"marathon,scoreathon,intermediate,grandmaster,gm plus,intense,intense plus,extreme,infinite,sprint,blitz,20g trainer,lightning,invisible",
marathon={
desc="a classic: clear 150 lines and you're done",
invscr_ordering=true,
stats=split"level,left,time",
qualify=lines_over,
over=lines_over,
getscore=scr_t
},
infinite={
desc="let's see you overflow that score counter",
stats=split"score,level,lines,time",
getscore=scr,
over=no
},
blitz={
desc="128 tetroms for a high score",
lv={goal=32},
stats=split"score,level,remain",
qualify=drops_over,
over=drops_over,
drop_target=128,
getscore=scr,
level_curve=csv[[999,0.005
96,0.005
95,0.2
72,1
64,5
63,1
32,15
31,10
1,30]],
sections=csv[[999,8,3,4,25,10
6,7,3,4,25,10
5,8,3,5,25,10
3,12,8,8,30,5
1,20,15,10,30,2]]
},
grandmaster={
desc="prove your skill",
over=leveling_over,
qualify=gm_nz,
lv={goal=128},
gm_eligible=true,
level_curve = csv[[1024,0.005
512,0.005
511,10
502,1
501,0.2
440,1
400,1
384,3
383,1
256,5
255,2
162,6
128,10
127,5
64,15
14,40
1,40]],
bags=3,
invscr_ordering=true,
stats=split"grade,level,time",
getscore=scr_gm,
sections=csv[[8,8,4,6,20,10
7,10,8,6,20,5
6,12,8,6,30,4
5,15,10,10,30,3
4,20,20,10,30,2
3,20,20,15,30,1
1,25,20,15,30,1]]
}
}
local a={}
modes.sprint=a
cpt(modes.marathon,a)
a.desc="clear 40 lines as quickly as possible"
a.linesneeded=40
a={}
modes.scoreathon=a
cpt(modes.marathon,a)
a.desc="go for a high score in 150 lines"
a.getscore=scr
a.qualify=yes
a.invscr_ordering=false
a.stats=split"score,time,level,left"
a={}
modes.intermediate=a
cpt(modes.grandmaster,a)
a.desc="walk the path towards mastery"
a.level_curve=csv[[768,0.005
640,0.005
639,1
600,1
512,5
511,2
416,5
400,8
384,10
383,5
338,10
274,20
256,20
255,12
192,15
144,20
128,40
127,20
14,60
1,60]]
a.sections=csv[[6,20,15,15,45,2
5,20,20,15,30,2
4,25,20,15,30,1
1,30,25,15,30,1]]
a={}
modes.invisible=a
cpt(modes.sprint,a)
a.desc="there is no garbage... oh nononono not like that!"
a.invisible=true
a.on_drop=function()
if lines > 20 then
ghost.draw=false
on_drop=nil
end
end
a={}
modes.lightning=a
cpt(modes.sprint,a)
a.desc="a lightning storm is your only light"
a.flashies=dkflash
a.outline_only=true
a.yikes=false
a.on_drop=function()
if not yikes and (lines>0 or drops >=5) then
darken(ltflash)
yikes = true
end
if (lines>=30) flash_on_lock=false
if (lines>=35) ghost.draw=false
end
a={}
modes["gm plus"]=a
cpt(modes.grandmaster,a)
a.desc="increase the challenge with garbage."
a.on_level=function(newlv)
if (newlv<6) on_drop=garbage_every(14-newlv)
if (newlv==6) darken(dkflash)
if (newlv==7) darken(ltflash)
if (newlv==8) flash_on_lock=false
end
a={}
modes["20g trainer"]=a
cpt(modes.grandmaster,a)
a.desc="get used to 20g play here. lockdown starts slow."
a.level_curve=csv[[768,0.001
1,0.001]]
a.sections=csv[[6,12,6,8,25,3
5,15,10,10,30,2
4,20,15,12,30,2
3,25,20,15,30,1
2,25,20,15,40,1
1,25,20,15,60,1]]
a={}
modes.intense=a
cpt(modes.grandmaster,a)
a.desc="20g gets faster. can you survive?"
a.level_curve=csv[[1536,0.001
1,0.001]]
a.getscore=scr_lvltime
a.qualify=sec_nz
a.stats=split"section,level,time,drops"
a.sections=csv[[10,6,0,4,15,10
9,8,2,6,15,5
8,8,2,6,20,5
7,10,4,8,20,4
6,10,6,8,24,4
5,12,8,8,24,3
4,12,12,10,30,3
3,20,15,12,30,2
2,25,20,15,30,2
1,25,20,15,40,1]]
a.on_level=function(newlv)
if (newlv==11) darken(dkflash)
if (newlv==12) darken(ltflash)
end
a={}
modes["intense plus"]=a
cpt(modes.intense, a)
a.desc="and now with a garbage flood."
a.on_level=function(newlv)
if (newlv<8) on_drop=garbage_every(8-newlv\2)
if (newlv==8) darken(dkflash)
if (newlv==9) darken(ltflash)
if (newlv==10) flash_on_lock=false
if newlv==12 then
on_drop=nil
invisible=true
end
end
a={}
modes.extreme=a
cpt(modes.intense,a)
a.desc="good luck sucker"
a.sections=csv[[14,4,2,5,12,10
12,4,2,5,13,10
10,4,2,5,15,10
8,5,2,5,15,10
7,6,2,5,15,5
6,8,2,6,15,5
5,10,4,8,17,4
4,12,6,8,20,3
3,12,12,10,24,3
2,15,15,12,30,2
1,20,20,15,30,2]]
a.level_curve=csv[[2048,0.001
1,0.001]]
a.on_level=function(newlv)
if (newlv<9) on_drop=garbage_every(6-newlv\3)
if (newlv==9) darken(dkflash)
if (newlv == 11) darken(ltflash)
if (newlv == 13) flash_on_lock=false
if newlv == 15 then
invisible=true
on_drop=nil
end
end
end
-->8
--grandmaster grading
gm_combo_value=csv[[1,1,1.1,1.2,1.3,1.4,1.5,1.75,2,2,2,2,2,2,2
1,1.2,1.3,1.4,1.5,1.75,2,2.25,2.5,2.75,3,3,3,3,3
1,1.3,1.5,1.75,2,2.25,2.5,2.75,3,3.33,3.66,4,4,4,4
1,1.5,1.75,2,2.3,2.75,3.5,4,4.25,4.5,4.75,5,5,5,5
1,1.5,1.75,2,2.5,3,3.5,4,4.5,5,5.5,6,6,6,6,6,6]]
function gm_grade() --for in-game stats display
if(gm_glv>=17 and not topout)return "?????",8
return parse_gm_ordinal(gm_ordinal(over()))
end
function calc_gm_values(gm_lv)
if(gm_lv <= 0) return split"10,20,35,80,120",120
if(gm_lv<=3) return split"8,16,30,60,120",split"100,75,60,50"[gm_lv]
if(gm_lv<=5)return split"5,10,22,50,80",split"40,35,30"[gm_lv-5]
if(gm_lv<=8)return split"4,8,20,40,75",25
--s-ranks
if(gm_lv<=18)return split"3,8,16,35,65",split"23,22,20,20,18"[(gm_lv-8)\2]
if(gm_lv<=22)return split"2,7,14,30,60",split"20,20,15,15,10"[gm_lv-18]
return split"2,5,18,35,65",10
end
function gm_ordinal(won)
local gml=gm_glv
if (gml>8) gml=((gml-1)&0xfffe)+1
return min(gml,0xff)+btoi(won)*0x100+btoi(won and gm_eligible and gml>26 and gametime<600)*0x1000
end
function fatboy(slim,phat)
return slim.."\^w"..phat.."\^-w"
end
function parse_gm_ordinal(val, long)
if(val>0x1000)return long and "\^wg\^-wrand\^wm\^-waster" or "\^wgm\^-w",10
if(val>0x11b)return long and "master-\^wm\^-w" or "m\^wm\^-w",14
local base=val%0xff
if (base < 9) return fatboy(long and "grade " or "",9-base),7
base=min((base-7)\2,9)
if(val>0x100)return fatboy(long and "master-" or "m",base),8
return fatboy(long and "grade s" or "s",base),9
end
-->8
--cartdata
function writedata()
local o=opt_strs
--version
dset(0,1000*version[1]+version[2])
--booleans, up to 16
dset(1, bitpack{gamev.locking_harddrop, gamev.invrot, gamev.bganim, gamev.progbar})
--sprite choices
dset(3,put_num(put_num(o[8].curr,16,o[7].curr),16,o[6].curr))
dset(4,put_num(o[10].curr,16,o[9].curr))
--range options
dset(6,o[6].curr)
dset(7,o[5].curr)
end
function readdata()
if(0==dget(0)\1000)return false
local o=opt_strs
--bools
local d,index=dget(1),split"0,1,3,2"
for i,b in ipairs(index) do
o[i].curr=get_bit(d,b)
end
--sprites
for i=0,4 do
o[6+i].curr=get_num(dget(3+i\3),16,i%3)
end
--ranges
o[6].curr=dget(6)
o[5].curr=dget(7)
end
function getscores(mode)
2023-07-23 23:08:54 +00:00
mode *= 3
return {
dget(13+mode),
dget(14+mode),
dget(15+mode)
}
end
function addscore(mode,score)
2023-07-23 23:08:54 +00:00
if (score==0)return
local s,inv=getscores(mode), invscr_ordering and -1 or 1
s[4]=score
local i=3
while 0<i do
2023-07-23 23:08:54 +00:00
if (s[i]!=0 and s[i+1]*inv<=s[i]*inv) break
s[i+1],s[i]=s[i],s[i+1]
i-=1
end
mode-=1
for n=1,3 do
dset(15+3*mode+n,s[n])
end
return i+1
end
-->8
--animations
anim={
--heads of linked lists. contains
--non-nil next exactly when the
--list is not empty. does not
--point straight to the first
--item so item removal has no
--special case
crushes={},
swooshes={},
new=function(t,a)
local listname = t.."es"
a.type,a.new,a.next=t,true,anim[listname].next
anim[listname].next=a
_ENV["upd_"..t](a)
end,
draw=function()
--drawing in correct order
for t in all({"swoosh","crush"})do
local lnm = t.."es"
local prev=anim[lnm]
local curr=prev.next
while curr do
if (not curr.wait and not anim[t](curr)) prev.next=curr.next
prev=curr
curr=curr.next
end
poke2(0x5f06,0x706)
end
end,
update=function()
clearing=false
local curr=anim.swooshes.next
while curr do
upd_swoosh(curr)
curr=curr.next
end
curr = anim.crushes.next
while curr do
upd_crush(curr)
curr=curr.next
end
end,
swoosh=function(a)
local baseframes = 10/clrspd --10 wide
local totalframes = baseframes+5 --5 swooshclrs
if a.age > totalframes then
dirty=true
return false
end
--outlines are bright during swoosh
flash_idx = #flashies
local ax,ay,ctx_age=a.x,a.y,a.age+1
for i,clr in ipairs(swooshclrs) do
ctx_age-=1
if (ctx_age < 0) return true
local m = min(ctx_age/baseframes,1)
rectfill(ax,ay,ax+60*m*m,ay+5,clr)
end
return true
end,
crush=function(a)
if (debris==3) return false
if (a.lag>0) return true
poke2(0x5f06,a.c)
local spr_base = 8*sprite.normal
local ret = false
for p in all(a.list) do
ret = ret or p.y<128
sspr(spr_base+p.i%2*3,p.i\2*3,3,3,p.x,p.y)
end
return ret
end
}
swooshclrs=split"10,11,12,12,7"
function upd_swoosh(a)
a.age+=1
clearing=clearing or a.age<10/clrspd+5
--10 blocks wide, 5 swooshclrs.
end
function upd_crush(a)
if a.list==nil then
a.list = {
{i=0,x=a.x,y=a.y,dx=-rnd(0.5),dy=rnd(1)-1.5},
{i=1,x=a.x+3,y=a.y,dx=rnd(0.5),dy=rnd(1)-1.5},
{i=3,x=a.x+3,y=a.y+3,dx=rnd(0.5),dy=rnd(1)-0.5},
{i=2,x=a.x,y=a.y+3,dx=-rnd(0.5),dy=rnd(1)-0.5}
}
if debris==2 then
deli(a.list,irnd1(4))
deli(a.list,irnd1(3))
end
end
if a.lag>0 then
a.lag-=1
return
end
for p in all(a.list) do
p.x+=p.dx
p.y+=p.dy
p.dy+=0.075
end
end
-- blue, green, yellow/orange, red/purple, grey with red
progcols=split"12,13,1,11,3,5,10,9,4,2,1,1,6,8,5"
-- blue, green, brown/orange, purple, grey with red
bgcols=split"1,12,3,11,4,9,2,14,5,8"
bg={data={},curr="",draw=function()
if(bg.curr)bg[bg.curr](bg.data)
end,
set=function(s,d)
d=d or {}
bg.data,bg.curr=d,s
d.list=d.list or {}
end,
grid=function(d)
if(not bganim)return
local dc=min(4,d.col or 0)
if(.92<rnd())add(d.list,{a=4*irnd1(32),b=0,vert=rnd{false,true},back=rnd{false,true}})
for l in all(d.list)do
if(228<=l.b)del(d.list,l)
l.b+=1
local x,y,p=l.b,l.a,l.b-100
if(l.back)x,p=128-x,228-x
local c=bgcols[dc*2+1]
if l.vert then
x,y=y,x
line(x,y,x,p,c)
else
line(x,y,p,y,c)
end
pset(x,y,bgcols[dc*2+2])
end end,
falling=function(d)
if(.2<rnd())add(d.list,{x=rnd(132)-2,y=-4,s=rnd".5",t=15+irnd1(7)})
for t in all(d.list)do
if(128<t.y)del(d.list,t)
t.y+=t.s
t.s=min(3,t.s+.05)
spr(t.t,t.x,t.y,.5,.5)
end
end
}
-->8
-- message queue
-- message format:
-- text - text to print
-- tx, ty - text x, text y
-- cs - list of colors for text
-- ct - frames per color
-- dur - total frames to show
-- pri - message priority
-- ties replace existing msg
function update_msgs()
local m = messages.next
while (m and m.t >= m.dur) m = m.next
if (m) m.t += 1
messages.next = m
end
function draw_msgs()
local m = messages.next
if (not m) return
print(m.text, m.tx, m.ty,
m.cs[m.t\m.ct%#m.cs+1])
end
function push_flatmsg(
cs,
text, tx, ty,
ct, dur,
pri
)
push_msg{
text=text, tx=tx, ty=ty,
cs=cs,ct=ct,dur=dur,
pri=pri}
end
function push_msg(m)
--m.sprs = m.sprs or {}
m.cs = m.cs or {7}
m.ct = max(m.ct, 1)
-- offset count and limit
-- align color timing
m.t=-1
m.dur-=1
local p = messages
repeat
local n = p.next
if not n or m.pri < n.pri then
p.next = m
m.next = n
return
end
if m.pri == n.pri then
p.next=m
m.next=n.next
return
end
p = n
until false
end
__gfx__
00000000777777006666660077777700766666007777770077777000777666006666660077777700777777007777770007777000077770000777700077777700
07007000766667006777760077777700677666007676760076667600766776006776760076666700777767007666670077666700766667007766770077777700
00770000767767006766760077667700676666007767660076777600767676006776760076667700777667007666760076667600767767007600770077777700
00770000767767006766760077667700666666007676760076767600676767006666660076677700776667007667760076677600767767007600760077777700
07007000766667006777760077777700666666007767660077777600677667006767760076777700766667007677760076777600766667007777760077777700
00000000777777006666660077777700666666007666660006666600666777006666660077777700777777007766660007666000077770000776600077777700
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000070c0000cc0009009000aa00aa00bb00b000e000e0088000080000000000000000505050505550550555555555500000000000000000000000000055000
77770070ccc00c00999009000aa00aa0bb000bb0eee00ee008800880000000000000000000000000000000050000000500000000000000000000000000055000
0000007000000c000000099000000000000000b000000e0000000800000000000000000000000005000000000000000500000000000550000055550000055000
00000070000000000000000000000000000000000000000000000000000000000000000000000000000000050000000500055000005005000050050055500555
0000070000000c00000099000aa00aa00000b00000000e0000000800000000000000000000000005000000050000000500055000005005000050050055500555
00000700ccc00c00999009000aa00aa00bb0bb00eee0ee0088008800000000000000000000000000000000000000000500000000000550000055550000055000
7777070000c0cc009000090000000000bb000b000e000e0008808000000000000000000000000005000000050000000500000000000000000000000000055000
00000700000000000000000000000000000000000000000000000000000000000000000000000000000000050000000500000000000000000000000000055000
00000000000000000000000000000000000000000000000077707770777077707770000000000000000000000000000077777770770770000000000000000000
10000000000000000000000000000000000000000000000070707070777070707070000000000000000000000000000070070707700707070000000000000000
2100000000088880000cccc0000dddd0000000000000000070007070777077007070000077707070707707770000000070070707700707070000000000000000
321000000080000800c0000c00d0000d000000000000000070007070707077007070000007007070707000700000000077070770770777070000000000000000
421000000080000800c0000c00d0000d000000000000000070707070707070707070000007007770700700700000000077070770700707700000000000000000
51000000080008800c000cc00d000dd0000000000000000077707770707077707770000007007770707700700000000007070707700707070000000000000000
6d100000080080000c00c0000d00d000000000000000000000000000000000000000000000000000000000000000000007070707700707070000000000000000
76d10000080800000c0c00000d0d0000000000000000000000000000000000000000000000000000000000000000000070070707777707070000000000000000
82100000080800000c0c00000d0d0000000000000000000077700707007707700000000000000000000000000000000000000000000000000000000000000000
94210000080800000c0c00000d0d0000000000000000000070700707070707070000000000000000000000000000000000000000000000000000000000000000
a9421000088000000cc000000dd00000000000000000000070770707077707070000000000000000000000000000000000000000000000000000000000000000
b3210000088000000cc000000dd00000000000000000000007770777070707700000000000000000000000000000000000000000000000000000000000000000
cd100000aaaa00006666000099990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
d1000000a99a00006556000094490000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
e2100000a9aa00006566000094990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
f6d51000aaaa00006666000099990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
8888888888888800999999999999900aaaaaaaaaaaaaa00bbbbbbbbbbbbbbbbb0cccccccccc0eeeeeeeeeee00000000000000000000000000000000000000000
8777777777777800977777777779900a777777777777a00b7777777777777bb07777777777c07777777777e00000000000000000000000000000000000000000
8788888888888800979999999999000a7aaaaaaaaaaaa00b7bbbbbbbbbbbbb0cccccccccccc0eeeeeeeeeee00000000000000000000000000000000000000000
8888888888888800979999999999000aaaaaaaaaaaaaa00b7bbbbbbbbbbbb0ccccccccccccc0eeeeeeeeeee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb00000b7bb0cc00000000c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb0000b7bb07cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb000b7bb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb00b7bb00c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097999999990000000000a7aa0000000b7bb0b7bb000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097997777990000000000a7aa0000000b7bbb7bb0000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097999999900000000000a7aa0000000b7bbbbbb0000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097999999900000000000a7aa0000000b7bbbbbbb000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb0bbbbb00c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb00bbbbb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb000bbbb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb0000bbb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb00000bb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb000000b0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb00000000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097990000000000000000a7aa0000000b7bb00000000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097999999999999990000a7aa0000000b7bb00000000c7cccc0e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097997777777777790000a7aa0000000b7bb00000000c7cc770e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008788000000097999999999999999000a7aa0000000b7bb00000000c7cccc0e7ee0c7cc0e7ee000e7ee00000000000000000000000000000000000000000
000008888000000099999999999999999000aaaa0000000bbbb00000000cccccc0eeee0cccc0eeee000eeee00000000000000000000000000000000000000000
__label__
55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
56666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666665
56777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777765
56700000000000000000000000000c00000090000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000ccc009990000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
5670000bb0000000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000765
5670000000000000000000000000000000000000000000000000000000000000000000000aa00000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000088000000000000000000000000000000000000000000000000000765
5670000000000000000000000000000000000000000000000000000000000000000000000880000000000000000000000aa00000000000000000000000000765
5670000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000aa00000000000000000000000000765
56700900000000000000000000000000000000000000000000000000000000008800000000000008800000000000000000000000000000000000000900000765
56799900000000000000000000000000000000000000000000777070707770777077707770777000880000000000000000000000000000000000099900000765
56700000000000000000000000000000000000000000000000766070706760767076607770766000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000775067605750776077507670775000000007777bb0000000000000000000000000000000000765
5670000000000000000000000000000000000000000000000076007670070076707600757076000000000000bb00000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000777075700700757077707070777000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000666060600600606066606060666000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000555050500500505055505050555000000000000000000000000000000000000000000000000765
5670000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000765
567000000000000000000000000000000000000000000000000eee0000000000000000000000000000000000000000000000e000000000000000000000000765
5670000000000000000008888888888888800999999999999900aaaaaaaaaaaaaa00bbbbbbbbbbbbbbbbb0cccccccccc0eeeeeeeeeee00000000000000000765
5670000000000000000008777777777777800977777777779900a777777777777a00b7777777777777bb07777777777c07777777777e00000000000000000765
5670000000000000000008788888888888800979999999999000a7aaaaaaaaaaaa00b7bbbbbbbbbbbbb0cccccccccccc0eeeeeeeeeee00000000000000000765
5670000000000000000008888888888888800979999999999000aaaaaaaaaaaaaa00b7bbbbbbbbbbbb0ccccccccccccc0eeeeeeeeeee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb00000b7bb0cc00000000c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb0000b7bb07cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb000b7bb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb00b7bb00c7cc000e7ee0c7cc0e7ee000e7ee00000000000900000765
567000000000000000000000008788000000097999999990000000000a7aa0000000b7bb0b7bb000c7cc000e7ee0c7cc0e7ee000e7ee00000000099900000765
5670000000000000000000000087880000000979977779900000aa000a7aa0000000b7bbb7bb0000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
5670000000000000000000000087880000000979999999000000aa000a7aa0000000b7bbbbbb0000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000c00000008788000000097999999900000000000a7aa00e0000b7bbbbbbb000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000ccce00008788000000097990000000000000000a7aa0eee000b7bb0bbbbb00c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
56700000000000000000eee0008788000000097990000000000000000a7aa0000000b7bb00bbbbb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb000bbbb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000880000008788000000097990000000000000000a7aa0000000b7bb0000bbb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000088000008788000000097990000000000000000a7aa0000000b7bb00000bb0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb000000b0c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb00000000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097990000000000000000a7aa0000000b7bb00000000c7cc000e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097999999999999990000a7aa0000000b7bb00000000c7cccc0e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097997777777777790000a7aa0000000b7bb00000000c7cc770e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000008788000000097999999999999999000a7aa0000000b7bb00000000c7cccc0e7ee0c7cc0e7ee000e7ee00000000000000000765
567000000000000000000000aa8888000000099999999999999999000aaaa0000000bbbb00000000cccccc0eeee0cccc0eeee000eeee00000000000000000765
567000000000000000000000aa00000000000000000000000000000000000000000000ccc0000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900000000765
56700000000000000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000000000099900000000765
56700000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
567000000000000000000000000000000000000000000000000000000000000000000000000000000aa000000000000000000000000000000000000000000765
567000000000000000000000000000000000000000000000000007707770777077707770070000000aa00000000000000000000000000000000000000000b765
56700000000000000000000000000000000000000000000000007000070070707070070007000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000007770070077707700070007000000000000000000000000000000000000000000000000000765
567000000000000000000000000000000000000000000000000000700700707070700700000000aa000000000000000000000000000000000000000000000765
567000000000000000000000000000000000000000000000000077000700707070700700070000aa000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000066600660660066600000000066606660666066606660606006606600000000000000000000000000000000000765
56700000000000000000000000000000000066606060606060000600000066606060606060600600606060606060000000000000000000000000000000000765
56700000000000000000000000000000000060606060606066000000000060606660660066600600666060606060000000000000000000000000000000000765
56700000000000000000000000000000000060606060606060000600000060606060606060600600606060606060000000000000000000000000000000000765
56700000000000000000000000000000000060606600666066600000000060606060606060600600606066006060000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000066066606660666006606600066000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000606060600600060060606060600000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000606066600600060060606060666000000000000000000000000000000000000000000000000765
56700000000000000000007777000000000000000000000000606060008600060060606069996000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000660060000680666066006060660000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000060606660066060600000066006600660666066600660000000000000000000000000000000000000000765
56700000000000000000000000000000000000000060600600600060600000600060006060606069006000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000066600600600066600000666060006060660966006660000000000000000000000000000000000000000765
56700000000000000000000000000000000000000060600600606060600000006060006060606060000060000000000000000000000000000000000000000765
56700000000000000000000000000000000000000060606660666060600000660006606600606066606600000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ccc000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000090000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000009990000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000007777000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000077770007777000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
567000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000765
567000000000000000000088000000000000000000000000000000000000000000000000000000000000000000000000000000000000ccc00000000000000765
56700000000000000000000880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56705550000050500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700050000050500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700050000055500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700050000000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700050050000500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000765
56777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777765
56666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666665
55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555
__gff__
00000000000000000000000000000000671c499a3b8e28000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__map__
404142434445464748494a000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
505152535455565758595a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
606162636465666768696a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000002a2b2a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000002b2a2b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
__sfx__
000100001403014030130301203011030100300f0300c00008000020000100028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000
000200001a0301e03022030260201b0001a000190001900018000180001800028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000
000200002a03026030220301e0201b0001a000190001900018000180001800028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000
00050000205502655020550265503050030500305003050030500335003350028500275002750028500285002850028500285002850027500275002750027500275002850028500295002a5002a5002a5002b500
00050000205501a550205501a5503050030500305003050030500335003350028500275002750028500285002850028500285002850027500275002750027500275002850028500295002a5002a5002a5002b500
00050000200402004026030260303000030000300003000030000330003300028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000
0105000020030200301a0401a0403000030000300003000030000330003300028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000
01050000257402075020750257403070030700307003070030700337003370028700277002770028700287002870028700287002870027700277002770027700277002870028700297002a7002a7002a7002b700
010500002874028740287402e7203070030700307003070030700337003370028700277002770028700287002870028700287002870027700277002770027700277002870028700297002a7002a7002a7002b700
00050000200301c040190401904000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000200000d05008040050300302002010010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00020000166100d050080400503003020020100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000200002b0102d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000200002502000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00040000130501305015040180301c02022000280002d0002f0003100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00040000130501305015050180401c03022020280002d0002f0003100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00040000130501305015050180501c04022030280202d0002f0003100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00040000130501305015050180501c05022040280302d0202f0103100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000400001705017050190401c0302002025010280002d0002f0003100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000400001b0501b0501d0501f04023030280202e0102d0002f0003100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000400001e0501e0502005022050260402b0303102033510345103100032000320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000400001b0501e0502105024050240502105024050270502a0502d05030050300502d050300503305036040390303c0203e01000000000000000000000000000000000000000000000000000000000000000000
000300002175023750277402a72027730227002170022700267002a70000700007000070000700007000070000700007000070000700007000070000700007000070000700007000070000700007000070000700
000100002f6603c6602f6603c6602f6603c6602e6603b6602966034660236502b6501c65024650176401c64010640126400a6400a640046300263001620016001260001600116000460010600076000d6000b600
35040000016000160001600046010660108601106013d600010600d06019060017500d75019750017400d74019740017300d73019730017200d72019720017100d71019710017150d71519715000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
650a00001955019550005000050019540145401454020500175501755000000195500000019550000000000019540145401454000500175501755000000205001750017500000000000000000000000000000000
610800000d0500d0500000000000190500000019050000000d0500d0500000000000190500000019050000000d0500d0500000000000190500000019050000000d0500d050000000000019050000001905000000
011000001025010250000000000000000000000000000000102501025000000000001025000000000000000000000000000000000000000000000000000000001025010250000000000000000000000000000000
610800000d0500d05000000000001905000000190501025010050100500000000000190500000019050000000d0500d0500000000000190500000019050000000d0500d050000000000019050000001905000000
05020000260302a0302e030320201b0001a000190001900018000180001800028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000
0502000036030320302e0302a0201b0001a000190001900018000180001800028000270002700028000280002800028000280002800027000270002700027000270002800028000290002a0002a0002a0002b000