Here's a new version of the editor/map engine.
Added proper smooth scrolling.(Hold in rmb and drag mouse on map to scroll, even while editing)
Added line paste, this lets you drag a line(And scroll, it's not limited to the screen, it anchors to the tile under the mouse when you started)..it highlights what it'll draw, just drag and let go to paste.
Means you can now do most walls in two clicks, rather than manually doing each tile.
doing lightmapping part, now..here's where it gets intresting ;)
;For ;Top Down;
;
;
;Map and fx editor.
;
;Set up code by Rob Farley.
;
;Editor V2.0 Coded by Antony Wells.
;
;Open Source.
;-[setup by Rob farley.]
Include "M_Engine.bb"
Graphics 800,600,32,2
HidePointer
Global overBase.base,hitBase.base
Global tileW#=32,tileH#=32
Global maxtile = 190
Global tiles = LoadAnimImage("gfx/tiles.png",tileW,tileH,0,maxtile)
Global cursor = LoadImage("gfx/cursor.png")
MaskImage cursor,255,0,255
SetBuffer BackBuffer()
font = LoadFont("Arial.tff",15)
SetFont font
;-------------]
Global cTile.tile
genTiles()
Color 128,128,128
newButton( 10,540,60,20,"Load")
newButton( 80,540,60,20,"Save")
Color 255,0,0
newbutton( 150,540,60,20,"Clear")
;newButton( 220,540,60,20,"U
tileV.tile=First tile
viewY=300
ViewX=600
fromX=20
fromY=20
dragB.base=newButton(GraphicsWidth()/2-40,viewY-10,80,20,"Drag")
dragC.base=newButton(ViewX-20,viewY/2-20,40,40,"Pull")
dragA.base=newButton(20-10,20-10,20,10,"#")
dragD.base=newButton(fromX+viewX-10,fromY+viewY-10,20,20,"//")
Color 20,128,128
newText(GraphicsWidth()-100,5,"Edit Modes")
aMode.base=newText(GraphicsWidth()-150,40,"Mode:Paste")
pasteM.base=newButton(GraphicsWidth()-80,20,50,20,"Paste")
fillM.base=newButton(GraphicsWidth()-80,50,50,20,"Fill")
lineM.base=newButton(GraphicsWidth()-80,80,50,20,"Line")
lightM.base=newbutton(GraphicsWidth()-80,110,50,20,"Lights")
;lightM.base=newButton(GraphicsWidth()-80,130,50,20,"
Global overTile.tile
;---
;---[ Map Specific]
;set up default blank map
initMap(555,555)
;-
Repeat
Cls:uiCycle();
mx#=MouseX()
my#=MouseY()
If MouseHit(1)
Select state
Case 0
If overTile<>Null cTile=overTile
End Select
EndIf
If MouseHit(2)
Select state
Case 0
If overTile<>Null
If ctile<>Null
tnTile.tile=Before cTile
Insert cTile Before overTile
Insert overTile After tnTile
EndIf
EndIf
End Select
EndIf
mxs=MouseXSpeed()
mys=MouseYSpeed()
FlushMouse
Select uiHit()
Case "Paste"
cMode=1
rename(amode,"Mode:Paste")
Case "Fill"
cMode=2
rename(amode,"Mode:Fill")
Case "Line"
cMode=3
rename(amode,"Mode:Line")
Case "Lights"
cMode=4
rename(aMode,"Mode:Lights")
Case "Drag"
viewY=mY-fromY
Case "Pull"
viewX=mX-fromX
Case "#"
fromX=mx-viewX/2
fromY=my
dragA\x=mx+20
dragA\y=my-10
; viewX=fromX
Case "//"
viewY=mY-fromY
viewX=mX-fromX
Default
If MouseDown(3)
If overTile<>Null
If Not MouseDown(1)
fromX=fromX+mxs
fromY=fromY+mys
dragA\Y=draga\y+mys
Else
viewX=viewX+mxs
viewY=viewY+mys
EndIf
EndIf
EndIf
End Select
FlushMouse
dragA\w=viewX
draga\x=fromX
dragD\x=viewX-10+fromX
dragD\y=viewY-10+fromY
dragB\y=viewY-10+fromY
DragB\x=viewX/2-40+fromX
dragC\x=viewX-20+fromX
dragC\y=viewY/2-20+fromY
mz=MouseZSpeed()
If mz>0
For mz=mz To 0 Step -1
tileV=After tileV
If tileV=Null tileV=First tile
Next
Else If mz<0
For mz=Abs(mz) To 0 Step -1
tileV=Before tileV
If tileV=Null tileV=Last tile
Next
EndIf
;-[ The following code contains the parts that actually edit the map)
renderMap()
dumpTiles(tileV,fromX,fromY,viewX,viewY)
If cTile<>Null DrawImage cTile\id,MouseX(),MouseY()
If Not ((mx>fromx And mx<(fromx+viewX) And my>fromY-10 And my<fromy+viewY) Or overBase<>Null Or hitBase<>Null)
tileX=mapx+Int(mx+xoff)/Int(tileW)
tileY=mapy+Int(my+yoff)/Int(tileH)
Color 255,0,0
Rect (tileX-mapX)*tileW-xoff,(tiley-mapY)*tileH-yoff,tileW,tileH,0
If MouseDown(1)
Select cMode
Case 4
If nullLights=False
; addLight()
nullLights=True
EndIf
Case 2
fillTile(cTile,tileX,tileY)
Case 3
If lineIn=False
startX=mx
startY=my
tileSX=tileX
tileSY=tileY
lineIn=True
Else
tileEX=tileX
tileEy=tileY
endX=mx
endY=my
lineHighLight(tileSx,tileSy,tileEx,tileEy)
EndIf
Default
pasteTile(cTile,tileX,tileY)
End Select
Else
If lineIn
;Line startx,starty,endx,endy
lineTile(ctile,tilesx,tilesy,tileex,tileey)
lineIn=False
EndIf
EndIf
If MouseDown(2)
Select cMode
Case 2,1,3,4
scrollMap(-mxs*0.7,-mys*0.7)
End Select
EndIf
EndIf
Color 255,255,255
; Rect fromX,fromY+viewY,ViewX,4
; Rect fromX+viewX,fromY,4,viewY
Rect fromX,fromY,viewX,viewY,0
renderGui()
;This lets you shift the mouse cursor to the closet button
;in the direction the mouse is moving when you press TAB
;This speeds up editing a lot.
If KeyDown(15)
cx#=Float(MouseX())+Float(mxs)*6
cy#=Float(MouseY())+Float(mys)*6
xb=Sgn(mxs)
yb=Sgn(mys)
cbase.base=Null
sd#=999999
If MilliSecs()>ws+500
For b.base =Each base
If b\is=ui_button And b<>overBase
ix#=b\x+b\w/2
iy#=b\y+b\h/2
xd#=ix-cx
yd#=iy-cy
bx=Sgn(xd)
by=Sgn(yd)
If bx=xb And by=yb
td#=Sqr(xd*xd+yd*yd)
If td<sd
cbase.base=b
sd=td
ws=MilliSecs()
EndIf
EndIf
EndIf
Next
If cbase<>Null
lockX=cbase\x+cbase\w/2
lockY=cbase\y+cbase\h/2
DrawImage cursor,lockx,lockY
Flip
Repeat
Until KeyDown(15)=0
MoveMouse lockX,lockY
FlushMouse
EndIf
EndIf
EndIf
DrawImage cursor,MouseX(),MouseY()
Color 255,0,0
If lineIn
Line (tilesx-mapx)*tileW+tileW/2-xoff,(tilesy-mapy)*tileh+tileH/2-yoff,endx,endy
EndIf
Color 255,255,255
Text 1,1,mxs+" >"+mys
;--
Flip
Until KeyDown(1)
Function saveMap()
End Function
Function loadMap()
End Function
Function genTiles()
For j=0 To maxTile-1
t.tile =New tile
t\id=CreateImage(tileW,tileH)
CopyRect 0,0,tileW,tileH,0,0,ImageBuffer(tiles,j),ImageBuffer(t\id)
If imageEmpty(t\id)
FreeImage t\id
Delete t
EndIf
Next
End Function
Function dumpTiles(t.tile,x,y,maxWidth=250,maxHeight=250,smartDump=True,checkMouse=True)
ox#=x
oy#=y
If t=Null t=First tile
mx#=MouseX()
my#=MouseY()
Viewport x,y,maxWidth,maxHeight
If checkMouse overTile=Null
dispW=GraphicsWidth()
dispH=GraphicsHeight()
start.tile=t
Repeat
tc=tc+1
DrawImage t\id,x,y
If checkMouse
If mx>x And mx<x+tileW
If my>y And my<y+tileH
overTile=t
EndIf
EndIf
EndIf
If t=cTile
Color 255,255,255
Rect x,y,tilew,tileh,0
EndIf
x=x+tileW
If smartDump
If x=>ox+maxWidth
x=ox
y=y+tileH
If y=>oy+maxHeight-1 Exit ;y=0
EndIf
EndIf
t=After t
If t=Null t=First tile
Until t=start
Viewport 0,0,GraphicsWidth(),GraphicsHeight()
;DebugLog tc
End Function
Function uiCycle()
mx=MouseX()
my=MouseY()
Local but[3]
but[0]=MouseDown(1)
but[1]=MouseDown(2)
but[2]=MouseDown(3)
If but[0]=False hitBase=Null
overBase=Null
For b.base=Each base
If mx>b\x And mx<b\x+b\w
If my>b\y And my<b\y+b\h
overBase=b
If but[0]
If hitbase=Null hitBase=overBase
EndIf
EndIf
EndIf
Next
End Function
Function uiHit$()
If hitBase<>Null Return hitbase\id
End Function
Function uiOver$()
If overBase<>Null Return overBase\id
End Function
;--- DO CUBIC LIGHTING FOR CRYO NEXT< YO
Function imageEmpty(image,imagePoint=5000,maskR=255,maskG=0,maskB=255,resetMask=True)
SetBuffer ImageBuffer(image)
LockBuffer
iw=ImageWidth(tiles)
ih=ImageHeight(tiles)
For x=0 To ImageWidth(image)-1
For y=0 To ImageHeight(image)-1
rgb=ReadPixelFast(x,y)
r#=(rgb Shr 16) And 255
g#=(rgb Shr 8) And 255
b#=(rgb And 255)
If resetMask
If r=maskR And b=maskB And g=MaskG
WritePixelFast(x,y,0 Or (0 Shl 8) Or (0 Shl 16))
r=0
g=0
b=0
EndIf
EndIf
rd#=r-lr#
gd#=g-lg#
bd#=b-lb#
shift#=shift+Sqr(rd*rd+gd*gd+bd*bd)
lr#=r
lg#=g
lb#=b
Next
Next
UnlockBuffer
SetBuffer BackBuffer()
If shift>imagePoint Return False
Return True
End Function
;-SmallGUI ;just buttons for now, but will expand for the game it's self.
Type cache
Field img
Field x,y,width,height
End Type
Type base
Field is
Field x,y,w,h
Field id$,r,g,b
End Type
Global doCache=0
Const ui_button=1,ui_text=2
Function newButton.base(x,y,w,h,title$)
b.base= New base
b\is=ui_button
b\x=x
b\y=y
b\w=w
b\h=h
b\r=ColorRed()
b\g=ColorGreen()
b\b=ColorBlue()
b\id=title
doCache=True
Return b
; Return Handle(b)
End Function
Function newText.base(x,y,txt$)
b.base=New base
b\x=x
b\y=y
b\is=ui_text
b\id=txt
b\r=ColorRed()
b\g=ColorGreen()
b\b=ColorBlue()
doCache=True
Return b
End Function
Function rename(in.base,txt$)
in\id=txt
End Function
Function renderGui()
For b.base =Each base
Select b\is
Case ui_button
Color 20,20,20
Rect b\x+5,b\y+5,b\w,b\h,1
If hitbase=b
xm#=5
ym#=5
Else
xm=0
ym=0
EndIf
Color b\r,b\g,b\b
Rect b\x+xm,b\y+ym,b\w,b\h
Color 255,255,255
Rect b\x+xm,b\y+ym,b\w-1,b\h-1,0
Color 40,40,40
Rect b\x+xm+1,b\y+ym+1,b\w-1,b\h-1,0
Color 10,10,10
Text b\x+xm+b\w/2,b\y+ym+b\h/2,b\id,True,True
Color 255,255,255
Text b\x+xm+b\w/2,b\y+ym+b\h/2-3,b\id,True,True
Case ui_text
Color 5,5,5
Text b\x+4,b\y+4,b\id
Color b\r,b\g,b\b
Text b\x,b\y,b\id
End Select
Next
End Function
Function genCaches()
sx#=9999
sy#=9999
bx#=-9999
sy#=-9999
For b.base =Each base
x2#=b\x+b\w
y2#=b\y+b\h
If b\x<sx sx=b\x
If b\y<sy sy =b\y
Next
End Function
;Map Engine 2
;
;Original coded by Antony Wells
Type tile
Field id
End Type
Dim map.tile(0,0,0)
Dim info#(0,0,0,15) ;just temp info for the map editor alone.
Global mapWidth,mapHeight,mapDepth
Global xoff#,yoff#,mapX#,mapY# ;mapx,y in tiles, xoff/yoff offset in pixels(Within range of 0 to tileWidth-1)
Global tileWidth,tileHeight
Function scrollMap(x#,y#) ;in pixels.
xOff=xOff+x
yOff=yOff+y
If xOff<0
mapX=mapX-1
xoff=tileWidth-Abs(xoff)
Else If xOff>tileWidth
mapX=mapX+1
xoff=xoff-tileWidth
EndIf
; Return
If yOff<0
mapy=mapY-1
yoff=tileHeight-Abs(yoff)
Else If yOff>tileHeight
mapy=mapy+1
yoff=yoff-tileHeight
EndIf
; xoff=Wrap(xoff,tileWidth)
; ypff=Wrap(yoff,tileHeight)
End Function
;recursive wrap.
Function Wrap#(val#,top#)
If val<0
val=top-Abs(val)
EndIf
If val>top
val=val-top
EndIf
Return val
End Function
Function initMap(width,height,tileW2=32,tileH2=32,depth=4)
Dim map.tile(width,height,depth)
Dim info(width,height,depth,15)
mapWidth=width
mapHeight=height
tileWidth=tileW2
tileHeight=tileH2
mapDepth=depth
End Function
Function pasteTile(tile.tile,x,y,layer=1)
If x<0 Or x>mapWidth Or y<0 Or y>mapheight Or layer<0 Or layer>mapDepth Return
map(x,y,layer)=tile
End Function
Function fillTile(tile.tile,x,y,layer=1,smartFill=False)
If smartFill
Else
For mx=0 To mapWidth-1
For my=0 To mapHeight-1
map(mx,my,layer)=tile
Next
Next
EndIf
End Function
Function highLight(sx,sy,layer=1)
info(sx,sy,layer,1)=True
End Function
Function lineHighlight(sx#,sy#,ex#,ey#,layer=1)
xd#=ex-sx
yd#=ey-sy
If Abs(xd)>Abs(yd) steps=Abs(xd) Else steps=Abs(yd)
xi#=xd/Float(steps)
yi#=yd/Float(steps)
For steps=steps To 0 Step -1
highlight(sx,sy,layer)
sx=sx+xi
sy=sy+yi
Next
End Function
Function lineTile(tile.tile,sx#,sy#,ex#,ey#,layer=1)
xd#=ex-sx
yd#=ey-sy
If Abs(xd)>Abs(yd) steps=Abs(xd) Else steps=Abs(yd)
xi#=xd/Float(steps)
yi#=yd/Float(steps)
For steps=steps To 0 Step -1
pasteTile(tile,sx,sy,layer)
sx=sx+xi
sy=sy+yi
Next
End Function
Function clearMap()
Dim map.tile(mapWidth,mapHeight,mapDepth)
End Function
Function renderMap()
tileHorz=GraphicsWidth()/tileWidth ;how many tiles we can see horizontally.
tileVert=GraphicsHeight()/tileHeight ;vertically speaking, this is the same.
For td=1 To mapDepth
For tx=mapX To mapX+TileHorz
If tx>-1 And tx<mapWidth
For ty=mapY To mapY+tileVert
If ty>-1 And ty<mapheight
tile.tile=map(tx,ty,td)
If tile<>Null
ax=rx*tileWidth-xoff
ay=ry*tileHeight-yoff
DrawImage tile\id,ax,ay
If info(tx,ty,td,1)
info(tx,ty,td,1)=False
Color 255,255,255
Rect ax,ay,tileW,tileH,0
EndIf
EndIf
EndIf
ry=ry+1
Next
ry=0
EndIf
rx=rx+1
Next
Next
End Function