unpack = unpack or table.unpack local a = {} local function add(...) local arg = {...} if arg[2]=='brusheditor_window' then arg[1][arg[3]]={} arg[1][arg[3]]['params']={} arg[1][arg[3]]['params']['show']=false arg[1][arg[3]]['params']['Type']=arg[2] arg[1][arg[3]]['params']['x1']=arg[4] arg[1][arg[3]]['params']['y1']=arg[5] arg[1][arg[3]]['params']['w']=arg[6] arg[1][arg[3]]['params']['h']=arg[7] arg[1][arg[3]]['params']['name']=arg[3] arg[1][arg[3]]['params']['movable']=arg[8] arg[1][arg[3]]['params']['active']=true arg[1][arg[3]]['items']={} else _G[arg[2]](2,arg) end end function brusheditor_button(a,x,y,mx,my,e) if a==0 then graphics.fillRect(x.x1+y.x1,x.y1+y.y1,x.w,x.h,100,100,100) graphics.fillRect(x.x1+y.x1,x.y1+y.y1,x.w-1,x.h-1,200,200,200) if x.pressed==1 then graphics.fillRect(x.x1+y.x1+1,x.y1+y.y1+1,x.w-2,x.h-2,230,230,230) else graphics.fillRect(x.x1+y.x1+1,x.y1+y.y1+1,x.w-2,x.h-2,200,200,200) end graphics.drawText(x.x1 +(x.w-graphics.textSize(x.name))/2+y.x1, x.y1+y.y1+3 ,x.name,0,0,0) elseif a==1 then if x.pressed==1 and e==2 then x.pressed=0 end if y.x1+x.x1mx and y.y1+x.y1my then if e==2 then x.action(x.p1,x.p2) x.pressed=0 elseif e==1 then x.pressed=1 end end elseif a==2 then x[1][x[3]]['items'][x[4]]={} x[1][x[3]]['items'][x[4]]['params']={} x[1][x[3]]['items'][x[4]]['params']['Type']=x[2] x[1][x[3]]['items'][x[4]]['params']['show']=false x[1][x[3]]['items'][x[4]]['params']['x1']=x[5] x[1][x[3]]['items'][x[4]]['params']['y1']=x[6] x[1][x[3]]['items'][x[4]]['params']['w']=x[7] x[1][x[3]]['items'][x[4]]['params']['h']=x[8] x[1][x[3]]['items'][x[4]]['params']['action']=x[9] x[1][x[3]]['items'][x[4]]['params']['p1']=x[10] x[1][x[3]]['items'][x[4]]['params']['p2']=x[11] x[1][x[3]]['items'][x[4]]['params']['name']=x[4] elseif a==3 then end end function brusheditor_window(a,x,mx,my,e) if a==0 then graphics.fillRect(x.x1,x.y1,x.w-1,x.h-1,200,200,200) graphics.fillRect(x.x1+1,x.y1+1,x.w-1,x.h-1,100,100,100) graphics.fillRect(x.x1+1,x.y1,x.w-2,x.h-2) if x.movable==true then graphics.fillRect(x.x1,x.y1,x.w,10,150,150,255) graphics.drawText(x.x1 +(x.w-graphics.textSize(x.name))/2 ,x.y1+2,x.name,0,0,0) end elseif a==1 then if x.pressed==1 and e==2 then x.pressed=0 end if x.x1mx and x.y1my and x.movable==true then if e==1 then x.pressed=1 x.px=mx x.py=my end end if x.pressed==1 and e==3 then local nx=x.x1-x.px+mx local ny=x.y1-x.py+my if nx>-1 and nx+x.w<642 then x.x1=nx x.px=mx end if ny>0 and ny+x.h<424 then x.y1=ny x.py=my end end elseif a==2 then elseif a==3 then end end function brusheditor_text(a,x,y) if a==0 then graphics.drawText(x.x1+y.x1,x.y1+y.y1,x.name,0,0,0) elseif a==1 then elseif a==2 then x[1][x[3]]['items'][x[4]]={} x[1][x[3]]['items'][x[4]]['params']={} x[1][x[3]]['items'][x[4]]['params']['Type']=x[2] x[1][x[3]]['items'][x[4]]['params']['show']=false x[1][x[3]]['items'][x[4]]['params']['x1']=x[5] x[1][x[3]]['items'][x[4]]['params']['y1']=x[6]x[1][x[3]]['items'][x[4]]['params']['name']=x[4] elseif a==3 then end end function brusheditor_checkbox( a,x,y,mx,my,e ) if a==0 then graphics.fillRect(x.x1+y.x1,x.y1+y.y1,10,10) graphics.drawRect(x.x1+y.x1,x.y1+y.y1,10,10,0,0,0) graphics.drawText(x.x1+y.x1+15,x.y1+y.y1+1,x.name,0,0,0) if x.checked==true then graphics.fillRect(x.x1+y.x1+2,x.y1+y.y1+2,6,6,80,200,80) end elseif a==1 then if x.x1+y.x1mx and x.y1+y.y1my then if e==2 and x.checked==true then x.checked=false elseif e==2 and x.checked~=true then x.checked=true end end elseif a==2 then x[1][x[3]]['items'][x[4]]={} x[1][x[3]]['items'][x[4]]['params']={} x[1][x[3]]['items'][x[4]]['params']['Type']=x[2] x[1][x[3]]['items'][x[4]]['params']['show']=false x[1][x[3]]['items'][x[4]]['params']['x1']=x[5] x[1][x[3]]['items'][x[4]]['params']['y1']=x[6]x[1][x[3]]['items'][x[4]]['params']['action']=x[7] x[1][x[3]]['items'][x[4]]['params']['checked']=x[8] x[1][x[3]]['items'][x[4]]['params']['name']=x[4] elseif a==3 then end end function brusheditor_textbox( a,x,y,mx,my,e,k ) if a==0 then if x.pressed == 1 then graphics.drawRect(x.x1+y.x1,x.y1+y.y1,x.w,x.h,255,0,0) else graphics.drawRect(x.x1+y.x1,x.y1+y.y1,x.w,x.h,0,0,0) end graphics.drawText(x.x1+y.x1+2,x.y1+y.y1+3,x.text,0,0,0) elseif a==1 then if x.pressed==1 and e==1 then x.pressed=0 end if y.x1+x.x1mx and y.y1+x.y1my then if e==2 then x.active=true elseif e==1 then x.pressed=1 end end elseif a==2 then x[1][x[3]]['items'][x[4]]={} x[1][x[3]]['items'][x[4]]['params']={} x[1][x[3]]['items'][x[4]]['params']['Type']=x[2] x[1][x[3]]['items'][x[4]]['params']['show']=false x[1][x[3]]['items'][x[4]]['params']['x1']=x[5] x[1][x[3]]['items'][x[4]]['params']['y1']=x[6] x[1][x[3]]['items'][x[4]]['params']['w']=x[7] x[1][x[3]]['items'][x[4]]['params']['h']=x[8] x[1][x[3]]['items'][x[4]]['params']['max']=x[9] x[1][x[3]]['items'][x[4]]['params']['name']=x[4] x[1][x[3]]['items'][x[4]]['params']['text']='' elseif a==3 then if string.len(x.text)47 and my <123 and k==1 and my~=8 then x.text=x.text..mx elseif my==8 and k==1 then x.text=string.sub(x.text,0,string.len(x.text)-1) elseif my==13 and k==1 then x.active=false x.pressed=0 end end end function brusheditor_brushtable( a,x,y,mx,my,e,b ) if a==0 then local l=math.sqrt( #x.table ) local j=1 local i=1 xw=l*x.cellsize+1 graphics.fillRect(x.x1+y.x1,x.y1+y.y1,xw,xw,0,0,0) for k=1,#x.table do i=i+1 if x.table[k]==0 then graphics.fillRect(x.x1+y.x1+i*x.cellsize-x.cellsize*2+1,x.y1+y.y1+j*x.cellsize-x.cellsize+1,x.cellsize-1,x.cellsize-1,255,255,255) else graphics.fillRect(x.x1+y.x1+i*x.cellsize-x.cellsize*2+1,x.y1+y.y1+j*x.cellsize-x.cellsize+1,x.cellsize-1,x.cellsize-1,0,0,0) end if k%l==0 then j=j+1 i=1 end end elseif a==1 then if x.x1+y.x1mx and x.y1+y.y1my then local click = math.floor((mx-x.x1)/x.cellsize)+math.sqrt( #x.table )*math.floor((my-x.y1)/x.cellsize)+1 if x.tool=='brush0' and e==3 and x.press==1 then if b==1 and click <= #x.table then x.table[click]=255 elseif b==4 and click <= #x.table then x.table[click]=0 end elseif x.tool=='brush0' and e==1 then x.history={unpack(x.table)} x.historyL=1 x.press=1 elseif x.tool=='brush0' and e==2 then x.press=0 elseif (x.tool=="brush1" or x.tool=="brush2") and e==1 then local l=math.sqrt( #x.table ) if x.f~=true then x.history={unpack(x.table)} x.historyL=1 if b==1 and click <= #x.table then x.f=true x.f1= math.floor((mx-x.x1)/x.cellsize) x.f2= math.floor((my-x.y1)/x.cellsize) elseif b==4 and click <= #x.table then x.f=true x.f1= math.floor((mx-x.x1)/x.cellsize) x.f2= math.floor((my-x.y1)/x.cellsize) end elseif x.f==true then x.f=false local cx=math.floor((mx-x.x1)/x.cellsize) local cy=math.floor((my-x.y1)/x.cellsize) if x.f1 < cx then x.f1,cx=cx,x.f1 end if x.f2 < cy then x.f2,cy=cy,x.f2 end if b==1 and click <= #x.table then for i=0, math.sqrt( #x.table )-1 do for j=0, math.sqrt( #x.table )-1 do if x.tool=="brush1" then if cx=j+1 and cy-1=i then x.table[i*l+j+1]=255 end else if (cx<=j and x.f1>=j and (i==cy or i==x.f2)) or ( cy-1=i and ( cx==j or j==x.f1) ) then x.table[i*l+j+1]=255 end end end end elseif b==4 and click <= #x.table then for i=0, math.sqrt( #x.table )-1 do for j=0, math.sqrt( #x.table )-1 do if x.tool=="brush1" then if cx=j+1 and cy-1=i then x.table[i*l+j+1]=0 end else if (cx<=j and x.f1>=j and (i==cy or i==x.f2)) or ( cy-1=i and ( cx==j or j==x.f1) ) then x.table[i*l+j+1]=0 end end end end end end end end elseif a==2 then x[1][x[3]]['items'][x[4]]={} x[1][x[3]]['items'][x[4]]['params']={} x[1][x[3]]['items'][x[4]]['params']['Type']=x[2] x[1][x[3]]['items'][x[4]]['params']['show']=false x[1][x[3]]['items'][x[4]]['params']['x1']=x[5] x[1][x[3]]['items'][x[4]]['params']['y1']=x[6] x[1][x[3]]['items'][x[4]]['params']['w']=x[7] x[1][x[3]]['items'][x[4]]['params']['h']=x[8] x[1][x[3]]['items'][x[4]]['params']['action']=x[9] x[1][x[3]]['items'][x[4]]['params']['name']=x[4] x[1][x[3]]['items'][x[4]]['params']['filename']="" x[1][x[3]]['items'][x[4]]['params']['table']={} for t=1,121 do x[1][x[3]]['items'][x[4]]['params']['table'][t]=0 end x[1][x[3]]['items'][x[4]]['params']['history']={} x[1][x[3]]['items'][x[4]]['params']['historyR']={} x[1][x[3]]['items'][x[4]]['params']['historyL']=0 x[1][x[3]]['items'][x[4]]['params']['tool']="brush0" x[1][x[3]]['items'][x[4]]['params']['cellsize']=11 elseif a==3 then end end local function hide(...) local arg = {...} if #arg==2 then arg[1][arg[2]].params.show=false elseif #arg==3 then arg[1][arg[2]].items[arg[3]].params.show=false end end local function show(...) local arg = {...} if #arg==2 then arg[1][arg[2]].params.show=true elseif #arg==3 then arg[1][arg[2]].items[arg[3]].params.show=true end end local function ShowAll(a,x) for i in pairs(a) do a[i].params.active=false end show(a,x) a[x].params.active=true for i in pairs(a[x].items) do show(a,x,i) end end local function HideAll(a,x) for i in pairs(a) do if i~='name1' then hide(a,i) end end a[x].params.active=false a['name1'].params.active=true end local function screen() for i in pairs(a) do if a[i].params.show==true and a[i].params.active==false then _G[a[i].params.Type](0,a[i].params) for p in pairs(a[i].items) do _G[a[i].items[p].params.Type] (0,a[i].items[p].params,a[i].params ) end end end for i in pairs(a) do if a[i].params.show==true and a[i].params.active==true then _G[a[i].params.Type](0,a[i].params) for p in pairs(a[i].items) do _G[a[i].items[p].params.Type] (0,a[i].items[p].params,a[i].params ) end end end end local function keypress( mousex, mousey, button, event ) for i in pairs(a) do if a[i].params.show==true and a[i].params.active==true then _G[a[i].params.Type](1,a[i].params,mousex,mousey,event) for j in pairs(a[i].items) do if a[i].items[j].params.show==true then _G[a[i].items[j].params.Type]( 1,a[i].items[j].params,a[i].params,mousex,mousey,event,button ) end end end end return false end local function keyp( key, nkey, modifier, event ) for i in pairs(a) do if a[i].params.show==true and a[i].params.active==true then for j in pairs(a[i].items) do if a[i].items[j].params.show==true and a[i].items[j].params.pressed==1 then _G[a[i].items[j].params.Type]( 3,a[i].items[j].params,a[i].params,key,nkey,modifer,event ) end end end end return false end local function load(b,k) HideAll(a,"Open") local name = "Brushes/"..b.text..".ptb" local f=io.open(name,"r") if f==nil then tpt.throw_error("Cannot open file") else local t = {} ii = 1 repeat current_byte = f:read(1) if current_byte~= nil then t[ii]= string.byte(current_byte) ii=ii+1 end until current_byte == nil k.params['table']=t end end local function createnew(x,y) HideAll(a,'New Brush') a['name1'].items.bt.params['table']={} for t=1,tonumber(x.text)*tonumber(x.text) do a['name1'].items.bt.params['table'][t]=0 end a['name1'].items.bt.params['cellsize']=y.text end local save local function SaveAs(k,d) d.params.filename=k.text..".ptb" save(d) HideAll(a,'Save As') end save = function(t) if t.params.filename~="" and t.params.filename~=nil then fs.makeDirectory("Brushes") local out = io.open("Brushes/"..t.params.filename, "wb") local str = string.char(unpack(t.params.table)) out:write(str) out:close() else ShowAll(a,'Save As') end end local function changeb(x,y) x.tool=y x.f=false end local function Undo(x) if x.params.historyL==1 then x.params.historyR={unpack(x.params.table)} x.params.table = {unpack(x.params.history)} x.params.historyL=2 end end local function Redo(x) if x.params.historyL==2 then x.params.history={unpack(x.params.table)} x.params.table = {unpack(x.params.historyR)} x.params.historyL=1 end end function BrushEditor() tpt.register_step(screen) tpt.register_mouseclick(keypress) tpt.register_keypress(keyp) ShowAll(a,'name1') end local function ExitEditor() tpt.unregister_step(screen) tpt.unregister_mouseclick(keypress) tpt.unregister_keypress(keyp) for i in pairs(a) do hide(a,i) end end add(a,'brusheditor_window','name1',-1,0,643,426,false) add(a,'brusheditor_window','File_dialog',0,12,50,72,false) add(a,'brusheditor_window','Edit_dialog',29,12,50,36,false) add(a,'brusheditor_window','About_dialog',58,12,50,24,false) add(a,'brusheditor_window','New Brush',200,200,100,70,true) add(a,'brusheditor_window','Tools',50,50,30,100,true) add(a,'brusheditor_window','Open',200,200,100,70,true) add(a,'brusheditor_window','Save As',200,200,100,70,true) add(a,'brusheditor_window','Info',200,200,150,150,true) ------------------------------------------ -- Main -- ------------------------------------------ add(a,'brusheditor_button','name1','File',0,0,30,12,ShowAll,a,'File_dialog') add(a,'brusheditor_brushtable','name1','bt',100,0) add(a,'brusheditor_button','name1','Edit',30,0,30,12,ShowAll,a,'Edit_dialog') add(a,'brusheditor_button','name1','About',60,0,30,12,ShowAll,a,'About_dialog') add(a,'brusheditor_text','name1','Tools',10,40) add(a,'brusheditor_button','name1','Filled\nSquare',10,55,35,30,changeb,a['name1'].items.bt.params,'brush1') add(a,'brusheditor_button','name1','Square',10,90,35,15, changeb,a['name1'].items.bt.params,'brush2') add(a,'brusheditor_button','name1','Point',10,110,35,15, changeb,a['name1'].items.bt.params,'brush0') ------------------------------------------ -- New dialog -- ------------------------------------------ add(a,'brusheditor_textbox','New Brush','File1',60,16,30,12,4,3) add(a,'brusheditor_textbox','New Brush','size',60,31,30,12,4,3) add(a,'brusheditor_button','New Brush','Ok',10,50,35,13,createnew,a['New Brush'].items.File1.params,a['New Brush'].items.size.params) add(a,'brusheditor_button','New Brush','Cancel',55,50,35,13,HideAll,a,'New Brush') add(a,'brusheditor_text','New Brush','Width',10,19) add(a,'brusheditor_text','New Brush','Cell size',10,34) ------------------------------------------ -- File dialog -- ------------------------------------------ add(a,'brusheditor_button','File_dialog','New',0,0,50,12,ShowAll,a,'New Brush') add(a,'brusheditor_button','File_dialog','Open',0,12,50,12,ShowAll,a,'Open') add(a,'brusheditor_button','File_dialog','Save',0,24,50,12,save,a['name1'].items.bt) add(a,'brusheditor_button','File_dialog','Save As',0,36,50,12,ShowAll,a,'Save As') add(a,'brusheditor_button','File_dialog','Exit',0,48,50,12,ExitEditor) add(a,'brusheditor_button','File_dialog','Close',0,60,50,12,HideAll,a,'File_dialog') ------------------------------------------ -- Edit dialog -- ------------------------------------------ add(a,'brusheditor_button','Edit_dialog','Undo',0,0,50,12,Undo,a['name1'].items.bt) add(a,'brusheditor_button','Edit_dialog','Redo',0,12,50,12,Redo,a['name1'].items.bt) add(a,'brusheditor_button','Edit_dialog','Close',0,24,50,12,HideAll,a,'Edit_dialog') ------------------------------------------ -- About dialog -- ------------------------------------------ add(a,'brusheditor_button','About_dialog','Info',0,0,50,12,ShowAll,a,'Info') add(a,'brusheditor_button','About_dialog','Close',0,12,50,12,HideAll,a,'About_dialog') ------------------------------------------ -- Info -- ------------------------------------------ add(a,'brusheditor_text','Info','Tpt ingame brush editor\nVersion: 1\nAuthor: ssccsscc\n\nIf you have question post it\nin the thread on the tpt\nforum.',10,24) add(a,'brusheditor_button','Info','Go to tpt forum',5,111,140,13,platform.openLink,"http://powdertoy.co.uk/Discussions/Thread/View.html?Thread=21788") add(a,'brusheditor_button','Info','Ok',5,130,140,13,HideAll,a,'Info') ------------------------------------------ -- Open -- ------------------------------------------ add(a,'brusheditor_textbox','Open','File1',52,16,45,12,8,3) add(a,'brusheditor_button','Open','Ok',10,50,35,13,load,a['Open'].items.File1.params, a['name1'].items.bt ) add(a,'brusheditor_button','Open','Cancel',55,50,35,13,HideAll,a,'Open') add(a,'brusheditor_text','Open','Filename\nWithout ".ptb"',10,19) ------------------------------------------ -- Save As -- ------------------------------------------ add(a,'brusheditor_textbox','Save As','File1',52,16,45,12,8,3) add(a,'brusheditor_button','Save As','Ok',10,50,35,13,SaveAs,a['Save As'].items.File1.params, a['name1'].items.bt ) add(a,'brusheditor_button','Save As','Cancel',55,50,35,13,HideAll,a,'Save As') add(a,'brusheditor_text','Save As','Filename\nWithout ".ptb"',10,19) ------------------------------------------