pico-8 cartridge // http://www.pico-8.com version 41 __lua__ --animator --custom animation tool --◆caoimhe ni chaoimh◆ --oakreef.ie --todo: -- export -- import -- delete button does't work function _init() debug = true poke(0x5f2d, 1) chars={} chari=0 layeri=0 cplayer=new_layer() --copied layer creation=nil playing = false timer = 0 clock = 0 fill = false ghost = false ghostw = false showcentre = true sheet={} --represents the sprite sheet toast = {timer=0,message=''} spritesheetname = 'spritesheet.png' metadataname = 'metasheet.png' tempimagename = 'temp.png' _online = type(stat(102)) == 'string' numf = 10 charlist = {'1','2','3','4','5','6','7','8','9','0','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',':',';','.',',',' ','-','='} alphabet = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'} generate_elements() active=nil backspace = false enter = false cancel = false sheet_width = 128 sheet_height = 64 input='' mouse = {x=0,y=0,l=false,r=false,m=false} keybuffer = {} --memset(0, 0, 0x2000) --cstore(0, 0, 0x2000) _import() update_current_layer() update_frame() end function toaster(message) toast.timer = 60 toast.message = message flip() rectfill(0,120,127,127,8) print(toast.message,1,121,7) end function _export() toaster('starting export') sheet = {} layers = {} -- add all layers to a single list for ci, c in pairs(chars) do for ai, a in pairs(c.anim) do for fi, f in pairs(a.frames) do for li, l in pairs(f.layers) do if not l:blank() then --disregard blank layers l:trim() add(layers, l) end end end end end -- sort by height and width toaster('sorting layers') layers = sort(layers) -- wipe sprite sheet memset(0, 0, 0x2000) -- starting from the top left of the sheet -- iterate over each column then row and -- try to add image in each space for i,l in pairs(layers) do toaster('packing ' .. i .. ' of ' .. #layers) for j,k in pairs(layers) do if k.drawn and k:eq(l) then l.loc = {} l.loc.x = k.loc.x l.loc.y = k.loc.y l.drawn = true break end end if not l.drawn then local drew = false for i=0,sheet_width-1 do for j=0,sheet_height-1 do if can_fit_on_sheet(l, i, j) then draw_to_sheet(l, i, j) drew = true break end end if drew then break end end if not drew then error("could not fit sprites on sheet") end end end toaster('exporting sheet') -- save sprite sheet to cart cstore(0, 0, 0x2000) -- export sprite sheet --export('stest.png') export(spritesheetname) -- plr={anim={ -- stand={ -- {20,{{0,24,10,9,-5,-17},{0,24,10,9,-5,-17}}}, -- {20,{{0,24,10,9,-5,-17},{0,24,10,9,-5,-17}}}, -- } -- walk=={ -- {20,{{0,24,10,9,-5,-17},{0,24,10,9,-5,-17}}}, -- {20,{{0,24,10,9,-5,-17},{0,24,10,9,-5,-17}}}, -- } -- }} -- iterate over each character and animation -- build lua code with animation data toaster('exporting metadata') local mds = '--animation data\n' for ci, c in pairs(chars) do mds = mds .. c.name .. ' = {anim={\n' for ai, a in pairs(c.anim) do mds = mds .. a.name .. '={' for fi, f in pairs(a.frames) do mds = mds .. '{' .. f.length .. ',{' for li, l in pairs(f.layers) do if l.loc != nil then mds = mds .. build_layer_def(l) .. ',' end end mds = sub(mds,1,#mds-1) mds = mds .. '}},\n' end mds = sub(mds,1,#mds-2) mds = mds .. '},\n' end mds = sub(mds,1,#mds-2) mds = mds .. '}}\n' end -- export animation data to text file printh(mds, 'metadata', true) -- build encoded animation data that can be reimported local mde = '' for ci, c in pairs(chars) do mde = mde .. ':' .. c.name for ai, a in pairs(c.anim) do mde = mde .. ';' .. a.name for fi, f in pairs(a.frames) do mde = mde .. '.' .. f.length for li, l in pairs(f.layers) do if l.loc != nil then mde = mde .. ',' .. l.loc.x .. ' ' .. l.loc.y .. ' ' .. l.trim.w .. ' ' .. l.trim.h .. ' ' .. l.offset.x .. ' ' .. l.offset.y end end end end end local mde = mde .. '=' if debug then printh(mde, 'debug', true) end -- wipe sprite sheet memset(0, 0, 0x2000) cstore(0, 0, 0x2000) -- write animation data to sprite sheet for i=1,#mde do if i > 0x1fff then error("metadata beyond bounds of sprite sheet storage") end poke(i-1, encode(sub(mde,i,i))) end -- export sprite sheet cstore(0, 0, 0x2000) --export('mtest.png') export(metadataname) memset(0, 0, 0x2000) cstore(0, 0, 0x2000) layers={} update_frame() end function build_layer_def(l) local str='{'..l.loc.x..','..l.loc.y str=str..','..l.trim.w..','..l.trim.h str=str..','..l.offset.x..','..l.offset.y str = str ..'}' return str end function encode(char) local num = 0 for i = 1,#charlist do if char == charlist[i] then num = i break end end if num == 0 then error("couldn't encode character " .. char) end return num end function decode(num) local char = charlist[num] if char == nil then error("couldn't decode character " .. num) end return char end function _import() local str = '' if _online then --we're probably on the bbs so load demo data str = ":plr;stand.20,0 45 10 9 -5 -17,8 0 9 7 -4 -22,16 24 2 3 -5 -13,6 43 2 2 4 -13,7 20 2 4 -2 -8,12 39 3 4 1 -8,15 38 5 5 -5 -4,17 0 3 5 1 -4,8 43 2 2 6 -13,9 33 2 2 -5 -10;walk.13,8 7 4 5 -3 -14,7 12 5 8 -2 -17,16 49 4 5 -1 -9,8 0 9 7 -4 -22,10 49 6 6 -4 -5,9 33 2 2 -3 -9,11 33 1 2 3 -10.17,18 29 5 4 -4 -13,0 12 7 12 -3 -16,17 13 3 5 3 -4,8 0 9 7 -4 -21,16 54 4 5 -5 -4,9 33 2 2 -5 -9,18 10 2 2 3 -9.13,12 33 3 6 0 -16,6 35 6 8 -3 -17,16 59 4 5 -1 -9,8 0 9 7 -4 -22,10 55 6 6 -4 -5,8 43 2 2 2 -11.17,17 43 3 5 2 -14,0 0 8 12 -4 -16,16 54 4 5 -5 -4,8 0 9 7 -4 -21,17 13 3 5 3 -4,9 20 7 7 0 -15;fire.5,10 61 6 3 -2 -15,9 27 9 6 8 -20,12 13 5 6 3 -19,8 43 2 2 3 -15,7 12 5 8 -3 -17,8 0 9 7 -5 -22,18 5 3 5 -3 -9,18 24 3 5 0 -9,17 0 3 5 1 -4,17 0 3 5 -4 -4.5,20 47 8 3 -1 -15,0 54 10 9 9 -21,10 43 7 6 4 -18,20 53 5 3 -2 -10,7 12 5 8 -2 -17,8 0 9 7 -4 -22,7 20 2 4 -2 -8,12 39 3 4 1 -8,17 0 3 5 1 -4,15 38 5 5 -5 -4.5,20 50 8 3 -1 -15,8 43 2 2 6 -15,10 43 7 6 5 -18,20 53 5 3 -2 -10,7 12 5 8 -2 -17,8 0 9 7 -4 -22,7 20 2 4 -2 -8,12 39 3 4 1 -8,17 0 3 5 1 -4,15 38 5 5 -5 -4;aim.20,20 50 8 3 -1 -15,8 43 2 2 6 -15,12 7 6 6 5 -18,20 53 5 3 -2 -10,7 12 5 8 -2 -17,8 0 9 7 -4 -22,7 20 2 4 -2 -8,12 39 3 4 1 -8,17 0 3 5 1 -4,15 38 5 5 -5 -4;rise.20,0 24 9 11 -3 -9,20 43 4 4 -7 -2.20,15 33 8 5 -3 -4,0 45 10 9 -5 -12,16 24 2 3 -5 -8,9 33 2 2 -5 -5,6 43 2 2 4 -8,8 43 2 2 6 -8,8 0 9 7 -4 -17;jump.20,20 15 5 4 -5 -16,7 12 5 8 -2 -17,8 0 9 7 -4 -22,9 33 2 2 -5 -12,0 35 6 10 -3 -10;rise.20,20 56 2 2 2 -20,16 19 5 5 -1 -18,7 12 5 8 -2 -17,16 54 4 5 -2 -4,8 0 9 7 -4 -22,20 38 2 5 0 -9;fall.20,20 0 3 5 4 -18,20 10 3 5 -6 -18,0 45 10 9 -5 -17,8 0 9 7 -4 -22,7 20 2 4 -2 -8,12 39 3 4 1 -8,20 56 2 2 -6 -20,20 56 2 2 5 -20,15 38 5 5 -5 -4,15 38 5 5 -1 -4" else --import any local data import(metadataname) reload(0, 0, 0x2000) if peek(0) != 0 then --we had some data to import, yay! for i =0,0x1fff do local num = peek(i) local inp = decode(num) if inp == '=' then break else str = str .. inp end end end end if #str > 0 then local imported_layers -- : start of new character -- ; start of new animation -- . start of new frame -- , start of new layer -- = end of data local model = split(str, ':') for i=1,#model do model[i] = split(model[i], ';') local char = new_char(model[i][1]) add(chars, char) for j=2,#model[i] do model[i][j] = split(model[i][j], '.') local anim = new_anim(model[i][j][1]) anim.parent = char add(char.anim, anim) for k=2,#model[i][j] do model[i][j][k] = split(model[i][j][k], ',') local frame = new_frame(k-1) frame.length = tonum(model[i][j][k][1]) frame.parent = anim add(anim.frames, frame) local xmin = 999 local ymin = 999 local xmax = -999 local ymax = -999 local origx = 12 local origy = 12 local previ = anim.frames[k-2] if previ then origx = previ.centre.x origy = previ.centre.y end for l=2,#model[i][j][k] do local props = split(model[i][j][k][l],' ') local layer = new_layer() layer.loc = {} layer.offset = {} layer.loc.x = tonum(props[1]) layer.loc.y = tonum(props[2]) layer.w = tonum(props[3]) layer.h = tonum(props[4]) layer.offset.x = tonum(props[5]) layer.offset.y = tonum(props[6]) layer.parent = frame frame.layers[l-1] = layer --need to reconstruct frame from sprite sheet --assume origin at 12,12 --check if offset and w/h of any sprite go outside of bounds --readjust if so if origx + layer.w + layer.offset.x - 1 > xmax then xmax = origx + layer.w + layer.offset.x - 1 end if origy + layer.h + layer.offset.y - 1 > ymax then ymax = origy + layer.h + layer.offset.y - 1 end if origx + layer.offset.x - 1 < xmin then xmin = origx + layer.offset.x - 1 end if origy + layer.offset.y - 1 < ymin then ymin = origy + layer.offset.y - 1 end end if xmin < 1 then origx -= xmin - 1 elseif xmax > 24 then origx -= xmax - 24 end if ymin < 1 then origy -= ymin -1 elseif ymax > 24 then origy -= ymax - 24 end frame.centre.x = flr(origx) frame.centre.y = flr(origy) end end end --actually import images now if not _online then import(spritesheetname) reload(0, 0, 0x2000) end for i,c in pairs(chars) do for j,a in pairs(c.anim) do for k,f in pairs(a.frames) do for l, layer in pairs(f.layers) do if layer.loc != nil then for x=0, layer.w - 1 do for y=0, layer.h - 1 do layer[flr(f.centre.x+layer.offset.x+x)][flr(f.centre.y+layer.offset.y+y)] = sget(flr(layer.loc.x+x), flr(layer.loc.y+y)) end end end -- this line is a kludge to stop a bug -- layers were disappearing if imported and re-exported -- don't know why that's happening but clones of the layers -- seem to export fine f.layers[l] = layer:clone() end end end end if #chars > 0 then chari = 1 end for i,c in pairs(chars) do if #c.anim > 0 then c.canim = 1 for i,a in pairs(c.anim) do if #a.frames > 0 then a.cframe = 1 end end end end if #get_char().anim > 0 then get_char().canim = 1 end if #get_anim().frames > 0 then frame_reset() end memset(0, 0, 0x2000) --cstore(0, 0, 0x2000) end end -- print contents of `tbl`, with indentation. -- `indent` sets the initial level of indentation. function tprint (tbl,indent) if not indent then indent = 0 end for k, v in pairs(tbl) do formatting = "" for i=1,indent do formatting = formatting .. " " end formatting = formatting .. k .. ":" if type(v) == "table" then print(formatting) tprint(v, indent+1) else print(formatting .. tostr(v)) end end end function split(str, separator) local parts = {} local buffer = '' for i = 1,#str do --print(type(str)) c = sub(str,i,i) if c == separator then if buffer != '' then add(parts, buffer) buffer = '' end else buffer = buffer .. c end end if buffer != '' then add(parts,buffer) end --if #parts == 1 then -- return parts[1] --end return parts end function error(message) cls() color(7) print(message) assert(false) end function can_fit_on_sheet(layer, x, y) if x+layer.trim.w > sheet_width then return false elseif y+layer.trim.h > sheet_height then return false end local boxa = {x=x,y=y,w=layer.trim.w,h=layer.trim.h} for k, l in pairs(layers) do if l.drawn then local boxb = {x=l.loc.x,y=l.loc.y,w=l.trim.w,h=l.trim.h} if coll(boxa, boxb) then return false end end end return true end function draw_to_sheet(layer, x, y) for i=1,layer.trim.w do for j=1,layer.trim.h do local col = layer[layer.trim.xn+i-1][layer.trim.yn+j-1] local x1,y1 = x+i-1, y+j-1 sset(x1, y1, col) end end layer.loc = {} layer.drawn = true layer.loc.x = x layer.loc.y = y end --quick and dirty bubble sort function sort(list) local changed = true while changed do changed = false for i=2,#list do if list[i-1]:lt(list[i]) then changed = true local holder = list[i-1] list[i-1] = list[i] list[i] = holder end end end return list end function _update60() clock+=1 read_input() if toast.timer > 0 then toast.timer -= 1 end if creation==nil then local l = get_layer() if l then if btnp(0) then for i=2,24 do for j=1,24 do l[i-1][j]=l[i][j] end end for j=1,24 do l[24][j]=0 end update_frame() elseif btnp(1) then for i=23,1,-1 do for j=1,24 do l[i+1][j]=l[i][j] end end for j=1,24 do l[1][j]=0 end update_frame() elseif btnp(2) then for i = 1,24 do for j = 2,24 do l[i][j-1]=l[i][j] end end for i = 1,24 do l[i][24] = 0 end update_frame() elseif btnp(3) then for i = 1,24 do for j = 23,1,-1 do l[i][j+1]=l[i][j] end end for i = 1,24 do l[i][1] = 0 end update_frame() end end else if backspace then if #input>0 then input=sub(input,0,#input-1) end elseif enter then if #input>0 then creation.name = input new_thing(creation) creation=nil input = '' update_frame() end elseif cancel then input = '' creation= nil elseif #input<5 then for i=1,#keybuffer do input=input..keybuffer[i] end end end local anim = get_anim() local frame = get_frame() if playing and anim != nil and frame != nil then timer += 1 if timer > frame.length then anim.cframe += 1 timer = 0 if anim.cframe > #anim.frames then anim.cframe = 1 end end end end function read_input() poke(0x5f30,1) --unsuppress pause if it was previously set local m = mouse m.x=stat(32) m.y=stat(33) local mb=stat(34) m.l=band(mb,1)>0--left m.r=band(mb,2)>0--right m.m=band(mb,4)>0--middle if m.l then if m.h then m.c = false else m.c = true m.h = true end else m.c = false m.h = false end if m.r then if m.hr then m.cr = false else m.cr = true m.hr = true end else m.cr = false m.hr = false end for i,e in pairs(elems) do if creation == nil and m.x >= e.x and m.x < e.x+e.w and m.y >= e.y and m.y < e.y+e.h then if m.c then e:onclick() elseif m.l then e:onhold() elseif m.cr then e:onrclick() end end end keybuffer = {} enter = false backspace = false cancel = false local keyin = stat(31) for i=1,#keyin do local key = sub(keyin, i, i) if key == 'p' or key == '\r' then poke(0x5f30,1) --suppress pause end if creation == nil then local f = get_frame() if f != nil then if key == 'w' then f.centre.y -= 1 elseif key == 'a' then f.centre.x -= 1 elseif key == 's' then f.centre.y += 1 elseif key == 'd' then f.centre.x += 1 elseif key == 'c' then cplayer = get_layer():clone() elseif key == 'p' or key == 'v' then f.layers[layeri] = cplayer:clone() update_frame() elseif key == '-' or key == '_' then char_dn() elseif key == '=' or key == '+' then char_up() elseif key == '[' or key == '{' then anim_dn() elseif key == ']' or key == '}' then anim_up() elseif key == '\'' or key == '"' then frame_dn() elseif key == '\\' or key == '|' then frame_up() end if f.centre.x > 24 then f.centre.x = 24 elseif f.centre.x < 1 then f.centre.x = 1 end if f.centre.y > 24 then f.centre.y = 24 elseif f.centre.y < 1 then f.centre.y = 1 end end else if key == '\b' then backspace = true elseif key == '\r' then enter = true elseif key == '/' or key == '\\' then cancel = true else for i=1,26 do if key == alphabet[i] then add(keybuffer, key) break end end end end end end function new_char(name) local char = { name=name, anim={}, canim=nil } char.clone = function(c) local clone = new_char() clone.name = c.name clone.anim = c.anim:clone() return clone end return char end function new_anim(name) local anim= { name=name, frames={}, cframe=nil } anim.clone = function(a) local clone = new_anim() clone.name = a.name for i=1,#a.frames do clone.frames[i] = a.frames[i]:clone() end return clone end return anim end function new_frame(name) local frame={ name=name, length=20, layers = {}, centre = {x=12,y=12}, tcol=0 } for i=1,numf do local layer = new_layer() add(frame.layers, layer) layer.parent = frame end frame.clone = function(f) local clone = new_frame() clone.name = f.name clone.length = f.length clone.centre.x = f.centre.x clone.centre.y = f.centre.y clone.tcol = f.tcol for i=1,numf do clone.layers[i] = f.layers[i]:clone() end return clone end return frame end function new_layer() local lay = {w=24,h=24} for i=1,24 do lay[i] = {} for j=1,24 do lay[i][j] = 0 end end lay.offset = {} lay.clone = function(l) local clone = new_layer() for i=1,24 do for j=1,24 do clone[i][j] = l[i][j] end end clone.parent = l.parent clone.offset.x = l.offset.x clone.offset.y = l.offset.y setmetatable(clone, getmetatable(l)) return clone end lay.trim = function(l) local xmin = 999 local ymin = 999 local xmax = 0 local ymax = 0 for i=1,l.w do for j=1,l.h do if l[i][j] != 0 then if i < xmin then xmin = i end if j < ymin then ymin = j end if i > xmax then xmax = i end if j > ymax then ymax = j end end end end if xmin <= xmax then l.offset = {} l.trim = {} l.offset.x = xmin - l.parent.centre.x l.offset.y = ymin - l.parent.centre.y l.trim.w = xmax - xmin + 1 l.trim.h = ymax - ymin + 1 l.trim.xn = xmin l.trim.yn = ymin elseif not l:blank() then local c = l.parent.parent.parent local a = l.parent.parent local f = l.parent error("trim failure "..c.name.." "..a.name.." "..f.name) end return l end lay.blank = function(l) for i=1,l.w do for j=1,l.h do if l[i][j] != 0 then return false end end end return true end -- local metatable = {} lay.eq = function (this, that) if this.trim.w != that.trim.w or this.trim.h != that.trim.h then return false end for i=1,this.trim.w do for j=1,this.trim.h do if this[this.trim.xn+i-1][this.trim.yn+j-1] != that[that.trim.xn+i-1][that.trim.yn+j-1] then return false end end end return true end lay.lt = function(this, that) if this.trim.h < that.trim.h then return true elseif this.trim.h == that.trim.h and this.trim.w < that.trim.w then return true end return false end -- setmetatable(lay,metatable) return lay end function new_thing(create_obj) local mode = create_obj.mode if create_obj.type=='character' then local char = nil if mode == 'copy' then char = get_char(create_obj.name):clone() else char = new_char(create_obj.name) end if char != nil then add(chars,char) chari=#chars end elseif create_obj.type=='animation'then local anim = nil if mode == 'copy' then anim = get_anim(create_obj.name):clone() else anim = new_anim(create_obj.name) end if anim != nil then local char = get_char() add(char.anim,anim) anim.parent = char char.canim = #char.anim end elseif create_obj.type=='frame'then local frame = nil if mode == 'copy' then frame = get_frame(#get_anim().frames+1):clone() else frame = new_frame(#get_anim().frames+1) end if frame != nil then local anim = get_anim() add(anim.frames,frame) frame.parent = anim anim.cframe = #anim.frames layeri = 1 end end end function delete_thing(type) if type == 'character' then local c = get_char() del(chars, c) if chari > #chars then chari = #chars end elseif type == 'animation' then local c = get_char() if c then local a = get_anim() del(c.anim, a) if c.canim > #c.anim then c.canim = #c.anim end end elseif type == 'frame' then local a = get_anim() if a then local f = get_frame() del(a.frames, f) if a.cframe > #a.frames then a.cframe = #a.frames end end end end function _draw() rectfill(0,0,128,128,5) for i,e in pairs(elems) do e:draw() end local m = mouse if clock%2!=0 or m.l or m.xanimw.x+animw.w or m.y < animw.y or m.y > animw.y+animw.h then line(m.x-2,m.y-1,m.x+2,m.y-1,0) line(m.x-2,m.y+1,m.x+2,m.y+1,0) line(m.x-1,m.y-2,m.x-1,m.y+2,0) line(m.x+1,m.y-2,m.x+1,m.y+2,0) line(m.x-1,m.y,m.x-2,m.y,7) line(m.x+1,m.y,m.x+2,m.y,7) line(m.x,m.y-1,m.x,m.y-2,7) line(m.x,m.y+1,m.x,m.y+2,7) end if creation then rectfill(1,32,126,50,5) rect(1,32,126,50,6) print('enter name for '..creation.type..':',3,34,6) print(input,50,43,6) --rect(6,32,120,64,6) end if toast.timer > 0 then rectfill(0,120,127,127,8) print(toast.message,1,121,7) end if debug then print('\x98 '..(stat(0)/20.48)..'%', 28, 106, 0) print('\x8c '..(stat(1)*100)..'%', 28, 112, 0) end end function new_element(x,y,w,h) local e = {x,y,w,h} e.x=x e.y=y e.w=w e.h=h e.bcol=5--background colour e.hcol=6--highlight colour e.i=1 --index e.onclick = function() end e.onrclick = function() end e.onrelease = function() end e.onhold = function() end e.label = '' e.draw= function(e) rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) print(e.label, e.x+2, e.y+2, e.hcol) end add(elems,e) return e end function dofill(layer,x,y,ncol,ocol) if x < 1 or x > 24 or y < 1 or y > 24 then return nil end if ocol == nil then ocol = layer[x][y] if ocol == ncol then return nil end end if layer[x][y] == ocol then layer[x][y] = ncol --store current working layers in spritesheet local xx = flr((layeri-1)/numf*2) local yy = flr((layeri-1)%flr(numf/2)) dofill(layer,x+1,y,ncol,ocol) dofill(layer,x-1,y,ncol,ocol) dofill(layer,x,y+1,ncol,ocol) dofill(layer,x,y-1,ncol,ocol) update_current_layer() update_frame() end end function char_up() chari+=1 if chari>#chars then chari=1 end update_frame() end function char_dn() chari-=1 if chari<1 then chari=#chars end update_frame() end function anim_up() local c = get_char() if c then c.canim+=1 if c.canim>#c.anim then c.canim=1 end update_frame() end end function anim_dn() local c = get_char() if c then c.canim-=1 if c.canim<1 then c.canim=#c.anim end update_frame() end end function frame_up() local a = get_anim() if a then a.cframe+=1 if a.cframe>#a.frames then a.cframe=1 end update_frame() end end function frame_dn() local a = get_anim() if a then a.cframe-=1 if a.cframe<1 then a.cframe=#a.frames end update_frame() end end function frame_reset() local a = get_anim() if not a or not a.frames or #a.frames < 1 then a.cframe = 0 return nil end a.cframe=1 update_frame() end function change_frame(ni) local a = get_anim() if a == nil or ni == a.cframe then return nil end -- memset(0, 0, 0x2000) a.cframe = ni -- local f = get_frame() -- if not a or not a.frames or #a.frames == 0 or not f then -- a.cframe = 0 -- return nil -- end -- for k=1,numf do -- local lay = f.layers[k] -- local xx = flr((k-1)/numf*2) -- local yy = flr((k-1)%flr(numf/2)) -- for i=0,23 do -- for j=0,23 do -- local c = lay[i+1][j+1] -- if c > 0 then -- sset(layw.x+i+xx*25,layw.y+j+yy*25,c) -- end -- end -- end -- end end function draw_frame(w) palt() if playing then local f = get_frame() for k=numf,1,-1 do local l = f.layers[k] for i=0,23 do for j=0,23 do local c = l[i+1][j+1] if c > 0 then rect( w.x+i*2, w.y+j*2, w.x+i*2+1, w.y+j*2+1, c) end end end end else if ghost and clock%2==0 then --and clock%2==0 then local anim = get_anim() if ghostw or (anim and anim.cframe > 1) then sspr(24,0,24,24,w.x,w.y,48,48) end end sspr(0,0,24,24,w.x,w.y,48,48) end end function update_current_layer() -- local l = get_layer() -- if l then -- l = l:trim() -- end end function update_frame() memset(0, 0, 0x1000) local f = get_frame() if f then local layers = f.layers for k=#layers, 1, -1 do for i=1,24 do for j=1,24 do local c = layers[k][i][j] if c > 0 then sset(i-1,j-1,c) end end end end local anim = get_anim() local onion_frame = anim.cframe - 1 if onion_frame < 1 then onion_frame = #anim.frames end if onion_frame > 0 and onion_frame != anim.cframe then local olayers = anim.frames[onion_frame].layers for k=#olayers, 1, -1 do for i=1,24 do for j=1,24 do local c = olayers[k][i][j] if c > 0 then sset(i+23,j-1,c) end end end end end end end function generate_elements() elems = {} --animation window animw = new_element(1,1,48,48) animw.bcol = 0 animw.hcol = 0 animw.draw = function(w) rectfill(w.x,w.y,w.x+w.w,w.y+w.h,0) local f = get_frame() local efrm = clock % 2 == 0 -- if ghost and efrm then -- draw_frame(w) -- end draw_frame(animw) if showcentre and f != nil and clock % 2 != 0 then local x = w.x+(f.centre.x-1)*2 local y = w.y+(f.centre.y-1)*2 rect(x, y, x+1, y+1, 1) pset( x+flr((clock/16)) % 2, y+flr(((clock+8)/16)) % 2, 7) end end animw.onclick = function(w) local x=flr((mouse.x-w.x)/2)+1 local y=flr((mouse.y-w.y)/2)+1 local l = get_layer() if l != nil then if fill then dofill(l,x,y,palet.i) else l[x][y] = palet.i --store current working layers in spritesheet -- local xx = flr((layeri-1)/numf*2) -- local yy = flr((layeri-1)%flr(numf/2)) -- sset(x+xx*25+76,y+yy*25,palet.i) update_current_layer() update_frame() end end end animw.onhold = animw.onclick --palette palet = new_element(51,1,12,48) palet.a=palet.w*palet.h/16 palet.s=sqrt(palet.a) palet.i=0 palet.draw = function(p) local w = p.w/p.s local h = p.h/p.s local s = p.s for i=0,w-1 do for j=0,h-1 do rectfill(p.x+i*s,p.y+j*s,p.x+i*s+s,p.y+j*s+s,i+j*w) end end local i=(p.i)%w local j=flr(p.i/w) rect(p.x+i*s, p.y+j*s, p.x+i*s+s, p.y+j*s+s,7) rect(p.x+i*s-1, p.y+j*s-1, p.x+i*s+s+1, p.y+j*s+s+1,0) end palet.onclick = function(p) local w = p.w/p.s local h = p.h/p.s local s = p.s local x=mouse.x-p.x local y=mouse.y-p.y if x>=0 and x=0 and y 0 then pset(l.x+i+xx*25,l.y+j+yy*25,c) end end end palt() end end if layeri>0 then rect( l.x + flr((layeri-1)/flr(numf/2))*25, l.y+((layeri-1)%flr(numf/2))*25, l.x + flr((layeri-1)/flr(numf/2))*25+25, l.y+((layeri-1)%flr(numf/2))*25+25, 7) end end layw.onclick = function(l) local x = mouse.x-l.x local y = mouse.y-l.y layeri = flr(x/25)*5+flr(y/25)+1 end function get_char() return chars[chari] end function get_anim() local char = get_char() if char then return chars[chari].anim[char.canim] end return nil end function get_frame() local anim = get_anim() if anim then return anim.frames[anim.cframe] end return nil end function get_layer() local frame = get_frame() if frame then return frame.layers[layeri] end return nil end local controls={ 'character', 'animation', 'frame'} timerelm = new_element(53,51,14,8) timerelm.draw = function(e) rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) print(timer,e.x+2,e.y+2,e.hcol) end toolb = new_element(61,67,14,8) toolb.bcol = 1 toolb.draw = function(e) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) print('p/f',e.x+2,e.y+2,e.bcol) if fill then print('f',e.x+10,e.y+2,e.hcol) else print('p',e.x+2,e.y+2,e.hcol) end end toolb.onclick = function(e) fill = not fill end ghostb = new_element(53,77,14,8) ghostb.bcol = 1 ghostb.onclick = function() ghost = not ghost end ghostb.draw = function(e) color(ghost and e.hcol or e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h) print('oni',e.x+2,e.y+2) end ghostwb = new_element(69,77,6,8) ghostwb.bcol = 1 ghostwb.onclick = function() ghostw = not ghostw end ghostwb.draw = function(e) color(ghostw and e.hcol or e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h) print('w',e.x+2,e.y+2) end centreb = new_element(53,87,18,8) centreb.bcol = 1 centreb.onclick = function() showcentre = not showcentre end centreb.draw = function(e) color(showcentre and e.hcol or e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h) print('orig',e.x+2,e.y+2) end local exportb = new_element(49,118,26,8) exportb.label = 'export' exportb.hcol = 15 exportb.onclick = function() _export() end local coords = new_element(58,61,0,0) coords.draw = function (e) local x = flr((mouse.x - animw.x)/2) local y = flr((mouse.y - animw.y)/2) if x < 0 then x,y = 0,0 end if x > 23 then x,y = 0,0 end if y < 0 then x,y = 0,0 end if y > 23 then x,y = 0,0 end if x < 10 then x = '0' .. x end if y < 10 then y = '0' .. y end print(x, e.x, e.y, 1) print(',', e.x + 8, e.y, 1) print(y, e.x + 11, e.y, 1) end framelendec = new_element(0,112,7,7) framelendec.draw=function(e) print('⬅️',e.x,e.y+2,e.hcol) end framelendec.onclick = function() local frame = get_frame() if frame != nil then frame.length -= 1 if frame.length < 1 then frame.length = 1 end end end frameleninc = new_element(18,112,7,7) frameleninc.draw=function(e) print('➡️',e.x,e.y+2,e.hcol) end frameleninc.onclick = function() local frame = get_frame() if frame != nil then frame.length += 1 if frame.length > 999 then frame.length = 999 end end end framelen = new_element(5,112,14,8) framelen.onclick = function() local frame = get_frame() if frame != nil then frame.length += 1 if frame.length > 999 then frame.length = 999 end end end framelen.onrclick = function() local frame = get_frame() if frame != nil then frame.length -= 1 if frame.length < 1 then frame.length = 1 end end end framelen.draw = function(e) rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) local frame = get_frame() if frame != nil then print(frame.length,e.x+2,e.y+2,e.hcol) end print('length',e.x-4,e.y-6) end playb = new_element(68,52,8,6) playb.bcol = 1 playb.draw = function(e) --rect(e.x,e.y,e.x+e.w,e.y+e.h,playing and e.hcol or e.bcol) print('➡️',e.x+1,e.y+1,playing and e.hcol or e.bcol) end playb.onclick = function() playing = not playing timer = 0 if not playing then update_frame() end end for i,v in pairs(controls) do local top = 50 local hgt = 18 local title= new_element(1,top+hgt*i-hgt,7,5) title.draw=function(e) print(v,e.x,e.y+2,e.hcol) end local prev = new_element(0,top+hgt*i+8-hgt,7,9) prev.draw=function(e) print('⬅️',e.x,e.y+2,e.hcol) end prev.onclick=function() if v == 'character' then char_dn() elseif v == 'animation' then anim_dn() elseif v == 'frame' then frame_dn() end end local next=new_element(26,top+hgt*i+8-hgt,7,9) next.draw=function(e) print('➡️',e.x,e.y+2,e.hcol) end next.onclick=function() if v == 'character' then char_up() elseif v == 'animation' then anim_up() elseif v == 'frame' then frame_up() end end local box=new_element(5,top+hgt*i+8-hgt,22,8) box.list = {} box.draw = function(e) rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) if v == 'character' then local char = get_char() if char then print(get_char().name,e.x+2,e.y+2,e.hcol) end elseif v == 'animation' then local anim = get_anim() if anim then print(get_anim().name,e.x+2,e.y+2,e.hcol) end elseif v == 'frame' then local frame = get_frame() if frame then print(get_frame().name,e.x+2,e.y+2,e.hcol) end end end local dele=new_element(40,top+hgt*i+8-hgt,6,8) dele.draw = function(e) rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) print('d',e.x+2,e.y+2,e.hcol) end dele.onclick=function() delete_thing(v) end local new=new_element(34,top+hgt*i+8-hgt,6,8) new.draw = function(e) rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) print('n',e.x+2,e.y+2,e.hcol) end new.onclick=function() if v == 'frame' then new_thing({mode='new',type=v}) update_frame() else creation={mode='new',type=v} end end -- local cpy=new_element(73,top+hgt*i+8-hgt,14,8) -- cpy.draw = function(e) -- rectfill(e.x,e.y,e.x+e.w,e.y+e.h,e.bcol) -- rect(e.x,e.y,e.x+e.w,e.y+e.h,e.hcol) -- print('cpy',e.x+2,e.y+2,e.hcol) -- end -- cpy.onclick=function() -- if v == 'frame' then -- new_thing({mode='copy',type=v}) -- else -- creation={mode='copy',type=v} -- end -- end end end --print text with colour and outline colour function print2(_str, _x, _y, _col, _ecol) print(_str,_x, _y+1,_ecol) print(_str,_x, _y-1,_ecol) print(_str,_x+1,_y, _ecol) print(_str,_x-1,_y, _ecol) print(_str,_x, _y, _col) end --collision between two boxes function coll(a,b) return a.x < b.x+b.w and a.x+a.w > b.x and a.y < b.y+b.h and a.y+a.h > b.y --return abs(a.x - b.x) * 2 < -- a.w + b.w and -- abs(a.y - b.y) * 2 < -- a.h + b.h end __gfx__ 000111000004944000110b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001113100094499401c00b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001113c00949f4f041100b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001133109499fff001c0b30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00113110949f9ff00111330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 031131100949ff000003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 131113100000ff000003b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 11011100033005005503b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0003b33003b006666603b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 003b013003b00465553b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 003b00133b01494660113b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 03b000133b03494000153b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 001100001100440000003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0011130011310055011003b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01cc11011cc1506601c0033000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0131cd0111dc6665511000bbb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 013d7c0131d7465001c00b3330000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0131dc01311d00600111b30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01311101331100060000b30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0011100011100000000b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0133b000b0300000000b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01313b03b03b000000b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 013003b3b33b000033b3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 130003b3b303b0000bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000994403103b00b33b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 004494994130031db333b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0149499490100011b303b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01d94911400c00000003b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01ddd1d10c00ccc00003b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 11111d1b000caca7c00033b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 333b113b00c7aaccac03bb0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 3033b03b000c77cc003b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1113b03b0c000cc0003b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 111bb03b0111300033b3bbb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000001111d13b011333311000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 003b100011103b01c3300c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 003bb10111113b01d001c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0003b10111cc03b11101110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0003b101131d030001113b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 003b0001131d33b011c03b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 031001011d3103b11c003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01c0c010113103b011003b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 11101015111003b001103b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1c0c00bb1d0500550b00000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0110100b110666600b00010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000110010004655503b0101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0011133110494600503b101100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 01cdd11dc149406000033bb03b1d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 1ddccddcd144000000003333b3110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 011d7cc71000100003b0003b31100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0001dcc100011111003b0bbb33b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00031cc10011c0c0003b3333b3300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0001b110001c011033bb000033110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0003333b00101c00bb00300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c0000000000111001110333b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 c000000c0000100001c0300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00cca0000c0111111110d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000cc0001101c01c00110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 ca0000ca001111101110000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0ca0000000101c003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000cc000c00011103b30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0c0000c0003b03b03b31000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00c0000000333b303b10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 000000000003b3113b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 __label__ 55555555555555555555555555555555555555555555555555000000000555555555555555555555555555555555555555555555555555555555555555555555 50000000000449944440000000000000000000000000000000077777770111115555555555555050505050505050505050505050505494405050505050505055 50000000000449944440000000000000000000000000000000070000070111115555555555555000000000000000000000000000009449940000000000000005 500000000994444999944000000000000000000000000000000700000701111155555555555550000000000000000000000000500949f4f04000000000000005 500000000994444999944000000000000000000000000000000700000701111155555555555550000000000000000000000000009499fff00000000000000005 5000000994499ff44ff0044000000000000cc0000000000000070000070111115555555555555000000000000000000000000050949f9ff00000000000000005 5000000994499ff44ff0044000000000000cc00000000000000700000701111155555555555550000000000000000000000000000949ff000000000000000005 5000099449999ffffff000000555500cc0000cccccc00000000777777703333355555555555550000000000000000000000000500000ff000000000000000005 5000099449999ffffff000000555500cc0000cccccc0000000000000000333335555555555555000003b03b00000000000000000000000000000000000000005 50000994499ff99ffff0055006666000000ccaaccaa77cc00052222223333333555555555555500000333b300000000000000050000000000000000000000005 50000994499ff99ffff0055006666000000ccaaccaa77cc0005222222333333355555555555550000003b3110000000000000000000000000000000000000005 500000099441111ff0000666666555500cc77aaaaccccaacc0522222233333335555555555555000000000000000000000000050000000000000000000000005 500000099441111ff0000666666555500cc77aaaaccccaacc0522222233333335555555555555000000000000000000000000000000000000000000000000005 50000000000111133110044665500000000cc7777cccc00000544444455555555555555555555000000000000000000000000050000000000000000000000005 50000000000111133110044665500000000cc7777cccc00000544444455555555555555507055000000000000000000000000000000000000000000000000005 5000000001133bbcc33bb11dd660000cc000000cccc0000000544444455555555555555007005000000000000000000000000050000000000000000000000005 5000000001133bbcc33bb11dd660000cc000000cccc0000000544444455555555555555775775000000000000000000000000000000000000000000000000005 50000000011333333bb3311110066000000000000000000000544444455555555555555007005000000000000000000000000050000000000000000000000005 50000000011333333bb3311110066000000000000000000000544444455555555555555507055000000000000000000000000000000000000000000000000005 500000000113333bb331111000000000000000000000000000566666677777775555555555555000000000000000000000000050000000000000000000000005 500000000113333bb331111000000000000000000000000000566666677777775555555555555000000000000000000000000000000000000000000000000005 50000000011331111dd0000000000000000000000000000000566666677777775555555555555000000000000000000000000050000000000000000000000005 50000000011331111dd0000000000000000000000000000000566666677777775555555555555000000000000000000000000000000000000000000000000005 50000000011333311110000000000000000000000000000000566666677777775555555555555000000000000000000000000050000000000000000000000005 50000000011333311110000000000000000000000000000000566666677777775555555555555000000000000000000000000000000000000000000000000005 50000000000111111000000000000000000000000000000000588888899999995555555555555000000000000000000000000050000000000000000000000005 50000000000111111000000000000000000000000000000000588888899999995555555555555505050505050505050505050505050505050505050505050505 50000000000333333bb0000000000000000000000000000000588888899999995555555555555000000000000000000000000050000000000000000000000005 50000000000333333bb000000000000000000000000000000058888889999999555555555555500000000000000000c000000000000000000000000000000005 5000000000033bb3333bb00000000000000000000000000000588888899999995555555555555000000000000000c00ccc000050000000000000000000000005 5000000000033bb3333bb0000000000000000000000000000058888889999999555555555555500000000000000000caca7c0000000000000000000000000005 5000000000033bb0033bb000000000000000000000000000005aaaaaabbbbbbb55555555555550000000000000000c7aaccac050000000000000000000000005 5000000000033bb0033bb000000000000000000000000000005aaaaaabbbbbbb555555555555500000000000000000c77cc00000000000000000000000000005 5000000000033bb0033bb000000000000000000000000000005aaaaaabbbbbbb5555555555555000000000000000c000cc000050000000000000000000000005 5000000000033bb0033bb000000000000000000000000000005aaaaaabbbbbbb5555555555555000000000000000000000000000000000000000000000000005 50000000033bb000033bb000000000000000000000000000005aaaaaabbbbbbb5555555555555000000000000000000000000050000000000000000000000005 50000000033bb000033bb000000000000000000000000000005aaaaaabbbbbbb5555555555555000000000000000000000000000000000000000000000000005 500000000111100000011110000000000000000000000000005ccccccddddddd5555555555555000000000000000000000000050000000000000000000000005 500000000111100000011110000000000000000000000000005ccccccddddddd5555555555555000000000000000000000000000000000000000000000000005 500000011cc00000011cc000000000000000000000000000005ccccccddddddd5555555555555000000000000000000000000050000330000000000000000005 500000011cc00000011cc000000000000000000000000000005ccccccddddddd55555555555550000000000000000000000000000003b0000000000000000005 500000011110000001111000000000000000000000000000005ccccccddddddd55555555555550000000000000000000000000500003b0000000000000000005 500000011110000001111000000000000000000000000000005ccccccddddddd55555555555550000000000000000000000000000003b0000000000000000005 500000011cc00000011cc000000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000050003b00000000000000000005 500000011cc00000011cc000000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000000000000000000000000000005 500000011111100001111110000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000050000000000000000000000005 500000011111100001111110000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000000000000000000000000000005 500000000000000000000000000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000050000000000000000000000005 500000000000000000000000000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000000000000000000000000000005 500000000000000000000000000000000000000000000000005eeeeeefffffff5555555555555000000000000000000000000050000000000000000000000005 55555555555555555555555555555555555555555555555555555555555555555555555555555000000000000000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555666666666666666555555555050505050505050505050505050505050505050505050505055 55665656566656665666556656665666566655555555555555555655555555555556555555555000000000000000000000000000000000000000000000000005 56555656565656565656565555655655565655555555555555555656665555555556551111155000000000000000000000000050000000000000000000000005 56555666566656655666565555655665566555555555555555555656565555555556511551115000000000000550000000000000000000000000000000000005 56555656565656565656565555655655565655555555555555555656565555555556511555115000000000050660000000000050000000000000000000000005 55665656565656565656556655655666565655555555555555555656565555555556511551115000000000066655000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555656665555555556551111155000000000046500000000000050000000000000000000000005 55555666666666666666666666665555556666666666666555555655555555555556555555555000000000000600000000000000000000000000000000000005 55555655555555555555555555565555556555556555556555555666666666666666555555555000000000000060000000000050000000000000000000000005 56666656665655566655555555566666556566556566556555555555555555555555555555555000000000000000000000000000000000000000000000000005 66655656565655565655555555565566656565656565656555555555551115111555511151115000000000000000000000000050000000000000000000000005 66555656665655566555555555565556656565656565656555555555551515151555515151515000000000000000000000000000000000000000000000000005 66655656555655565655555555565566656565656565656555555555551515151555515151515000000000000000000000000050000000000000000000000005 56666656555666565655555555566666556565656566656555555555551515151551515151515000000000000000000000000000000003b00000000000000005 555556555555555555555555555655555565555565555565555555555511151115155111511150000000000000000000000000500000033b0000000000000005 555556666666666666666666666655555566666666666665555555555555555555555555555550000000000000000000000000000000003b0000000000000005 555555555555555555555555555555555555555555555555555555555555566666666666666650000000000000000000000000500000003b0000000000000005 555555555555555555555555555555555555555555555555555555555555565555555555555650000000000000000000000000000000003b0000000000000005 55555555555555555555555555555555555555555555555555555555555556566655515111565000000000000000000000000050000000000000000000000005 56665665566656665666566656665566566555555555555555555555555556565655155155565000000000000000000000000000000000000000000000000005 56565656556556665656556555655656565655555555555555555555555556566655155115565000000000000000000000000050000000000000000000000005 56665656556556565666556555655656565655555555555555555555555556565555155155565000000000000000000000000000000000000000000000000005 56565656556556565656556555655656565655555555555555555555555556565551555155565000000000000000000000000050000000000000000000000005 56565656566656565656556556665665565655555555555555555555555556555555555555565000000000000000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555555555556666666666666665000000000000000000000000050000000000000000000000005 55555666666666666666666666665555556666666666666555555555555555555555555555555505050505050505050505050505050505050505050505050505 55555655555555555555555555565555556555556555556555555111111111111111511111115000000000000000000000000050000000000000000000000005 56666656665666566656665555566666556566556566556555555155555555555551515555515000000000000000000000000000000000000000000000000005 66655656555565565656555555565566656565656565656555555155115115511151515151515000000000000000000000000050000000000000000000000005 66555656655565566556655555565556656565656565656555555151515151551551515151515000000000000000000000000000000000000000000000000005 66655656555565565656555555565566656565656565656555555151515151551551515151515000000000000000000000000050000000000000000000000005 56666656555666565656665555566666556565656566656555555151515151551551515111515000000000000000000000000000000000000000000000000005 5555565555555555555555555556555555655555655555655555515115515151115151511151500000000001d000000000000050000000000000000000000005 55555666666666666666666666665555556666666666666555555155555555555551515555515000000000011000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555111111111111111511111115000000000000000000000000050000000000000000000000005 55555555555555555555555555555555555555555555555555555555555555555555555555555000000000000000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555666666666666666666655555000000000000000000000000050000000000000000000000005 56665666566656665666555555555555555555555555555555555655555555555555555655555000000000000000000000000000000000000000000000000005 56555656565656665655555555555555555555555555555555555655665666566655665655555000000000000000000000000050000000000000000000000005 56655665566656565665555555555555555555555555555555555656565656556556555655555000000000000000000000000000000000000000000000000005 56555656565656565655555555555555555555555555555555555656565665556556555655555000000000000000000000000050000000000000000000000005 56555656565656565666555555555555555555555555555555555656565656556556565655555000000000000000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555656655656566656665655555000000000000000000000000050000000000000000000000005 55555666666666666666666666665555556666666666666555555655555555555555555655555000000000000000000000000000000000011000000000000005 555556555555555555555555555655555565555565555565555556666666666666666666555550000000000000000000000000500000001c0000000000000005 56666656655555555555555555566666556566556566556555555555555555555555555555555000000000000000000000000000000000110000000000000005 666556556555555555555555555655666565656565656565555555555555555555555555555550000000000000000000000000500000001c0000000000000005 66555655655555555555555555565556656565656565656555555555555555555555555555555000000000000000000000000000000000111000000000000005 66655655655555555555555555565566656565656565656555555555555555555555555555555000000000000000000000000050000000000000000000000005 56666656665555555555555555566666556565656566656555555555555555555555555555555000000000000000000000000000000000000000000000000005 55555655555555555555555555565555556555556555556555555555555555555555555555555050505050505050505050505050505050505050505050505055 55555666666666666666666666665555556666666666666555555555555555555555555555555000000000000000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555555555555555555555555555000000000000000000000000050000000000000000000000005 55555555555555555555555555555555555555555555555555555555555555555555555555555000000000000000000000000000000000000000000000000005 55555555555555555555555555555555555555555555555555555555555555555555555555555000000000000000000000000050000000000000000000000005 56555666566555665666565655550000000555550555000555550055000500050005050555555000001100000000000000000000000000000000000000000005 56555655565656555565565655555555555555550555050555555055550555050505550555555000001131000000000000000050000000000000000000000005 56555665565656555565566655550000000555550005050555555055500555050005505555555000011cc1000000000000000000000000000000000000000005 565556555656565655655656555555555555555505050505555550555505550505050555555550000111dc000000000000000050000000000000000000000005 566656665656566655655656555500000005555500050005505500050005550500050505555550000131d7000000000000000000000000000000000000000005 5555555555555555555555555555555555555555555555555555555555555555555555555555500001311d000000000000000050000000000000000000000005 55555666666666666666555555550000000555550555000555550005055500050005050555555000013311000000000000000000000000000000000000000005 55555655555555555556555555550500050555550555055555550555055505050555550555555000001110000000000000000050000000000000000000000005 56666656665555555556666655550000000555550005000555550005000500050005505555555000000000000000000000000000000000000000000000000005 66655656555555555556556665550555550555550505550555555505050505055505055555555000000000000000000000000050000000000000000000000005 66555656665555555556555665550000000555550005000550550005000500050005050555555000000000000000000000000000000000000000000000000005 66655655565555555556556665555555555555555555555555555555555555555555555555555000000000000000000000000050000000000000000000000005 5666665666555555555666665555555555555555555555555fffffffffffffffffffffffffff5000000000000000000000000000000000000000000000000005 5555565555555555555655555555555555555555555555555f5555555555555555555555555f5000000000000000000000000050001100000000000000000005 5555566666666666666655555555555555555555555555555f5fff5f5f5fff55ff5fff5fff5f500000000000000000000000000001c000000000000000000005 5555555555555555555555555555555555555555555555555f5f555f5f5f5f5f5f5f5f55f55f5000000000000000000000000050011000000000000000000005 5555555555555555555555555555555555555555555555555f5ff555f55fff5f5f5ff555f55f500000000000000000000000000001c000000000000000000005 5555555555555555555555555555555555555555555555555f5f555f5f5f555f5f5f5f55f55f5000000000000000000000000050011100000000000000000005 5555555555555555555555555555555555555555555555555f5fff5f5f5f555ff55f5f55f55f5000000000000000000000000000000000000000000000000005 5555555555555555555555555555555555555555555555555f5555555555555555555555555f5000000000000000000000000050000000000000000000000005 5555555555555555555555555555555555555555555555555fffffffffffffffffffffffffff5505050505050505050505050505050505050505050505050505 55555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555