summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--vectorgfx.mod/.cvsignore6
-rw-r--r--vectorgfx.mod/vectorgfx.bmx406
2 files changed, 412 insertions, 0 deletions
diff --git a/vectorgfx.mod/.cvsignore b/vectorgfx.mod/.cvsignore
new file mode 100644
index 0000000..ae424d8
--- /dev/null
+++ b/vectorgfx.mod/.cvsignore
@@ -0,0 +1,6 @@
+vectorgfx.release.win32.i
+vectorgfx.debug.win32.a
+vectorgfx.debug.win32.i
+vectorgfx.release.win32.a
+.bmx
+doc
diff --git a/vectorgfx.mod/vectorgfx.bmx b/vectorgfx.mod/vectorgfx.bmx
new file mode 100644
index 0000000..f504141
--- /dev/null
+++ b/vectorgfx.mod/vectorgfx.bmx
@@ -0,0 +1,406 @@
+Rem
+bbdoc: noddybox.vectorgfx
+EndRem
+Module noddybox.vectorgfx
+
+ModuleInfo "Framework: 2D Vector Graphics classes"
+ModuleInfo "Copyright: Public Domain"
+ModuleInfo "Author: Ian Cowburn"
+ModuleInfo "Version: $Revision$"
+
+' $Id$
+
+Strict
+Import brl.linkedlist
+Import brl.math
+Import brl.endianstream
+Import brl.max2d
+Import noddybox.vector
+Import noddybox.algorithm
+
+Rem
+bbdoc: Defines a method for drawing vector lines
+EndRem
+Type TVectorGfxLineStyle Abstract
+ Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap) Abstract
+End Type
+
+Rem
+bbdoc: Set to use solid lines for drawing.
+about: This mode draws vector lines as solid colour lines using the current alpha, and is the default mode.
+EndRem
+Function VectorGfxSetSolid()
+ Static.linedraw=New LineSolid
+End Function
+
+Rem
+bbdoc: Set to use alpha lines for drawing.
+about: This mode draws vector lines using a @line_alpha for the lines, except for the end-points drawn with @end_alpha.
+EndRem
+Function VectorGfxSetAlpha(line_alpha:Double,end_alpha:Double)
+ Local l:LineAlpha=New LineAlpha
+ l.la=line_alpha
+ l.ea=end_alpha
+ Static.linedraw=l
+End Function
+
+Rem
+bbdoc: Set to use thick lines for drawing.
+about: This mode draws vector lines using solid line, surrounded by points of alpha @line_alpha.
+EndRem
+Function VectorGfxSetThickAlpha(line_alpha:Double)
+ Local l:ThickAlpha=New ThickAlpha
+ l.a=line_alpha
+ Static.linedraw=l
+End Function
+
+Rem
+bbdoc: Defines a vector graphics collision map.
+about: Collisions in the library a defined using a bitmask (allowing 32 collision masks).
+EndRem
+Type TVectorGfxCollisionMap
+
+ Field width:Int
+ Field height:Int
+ Field xoff:Int
+ Field yoff:Int
+ Field data:Int[,]
+
+ Rem
+ bbdoc: Create a collision map.
+ returns: The created collision map.
+ about: @width and @height are the size of the collision map.
+ EndRem
+ Function Create:TVectorGfxCollisionMap(width:Int, height:Int)
+ Local o:TVectorGfxCollisionMap=New TVectorGfxCollisionMap
+
+ o.width=width
+ o.height=height
+ o.xoff=0
+ o.yoff=0
+ o.data=New Int[width,height]
+
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Set the offset of the collision map.
+ about: @x and @y are the offsets into the co-ordinate space where the collision map lives.
+ EndRem
+ Method SetOffset(x:Int, y:Int)
+ xoff=x
+ yoff=y
+ End Method
+
+ Rem
+ bbdoc: Set a collision point.
+ returns: The current collision mask for that point, or zero if the point is out of the map's range.
+ about: @x and @y are the co-ordinates (in the objects co-ordinate space, not the collision map space)
+ EndRem
+ Method SetCollision(x:Int, y:Int, id:Int)
+ If x<xoff Or x>=xoff+width Or y<yoff Or y>=yoff+height
+ Return 0
+ EndIf
+
+ x:-xoff
+ y:-yoff
+
+ Local cur:Int=data[x,y]
+
+ data[x,y]:|id
+
+ Return cur
+ End Method
+
+ Rem
+ bbdoc: Clear the collision map
+ EndRem
+ Method Clear()
+ For Local x:Int=0 Until width
+ For Local y:Int=0 Until height
+ data[x,y]=0
+ Next
+ Next
+ End Method
+End Type
+
+
+Rem
+bbdoc: Defines a 2D vector graphics object
+EndRem
+Type TVectorGfxObject
+ Field lines:TList
+
+ Rem
+ bbdoc: The X co-ordinate of the object
+ EndRem
+ Field x:Int
+ Rem
+ bbdoc: The Y co-ordinate of the object
+ EndRem
+ Field y:Int
+ Rem
+ bbdoc: The angle of the object, as degrees*10. Must be within the range 0-3599 inclusive.
+ EndRem
+ Field ang:Int
+
+ Rem
+ bbdoc: Creates a new empty object
+ returns: The created object.
+ EndRem
+ Method New()
+ lines=CreateList()
+ x=0
+ y=0
+ ang=0
+ End Method
+
+ Rem
+ bbdoc: Adds a line to the object.
+ about: @line is the line to add.
+ EndRem
+ Method AddLine(line:TVectorGfxLine)
+ lines.AddLast(line)
+ End Method
+
+ Rem
+ bbdoc: Removes a line from the object.
+ about: @line is the line to remove.
+ EndRem
+ Method RemoveLine(line:TVectorGfxLine)
+ lines.Remove(line)
+ End Method
+
+ Rem
+ bbdoc: Loads the object from the supplied @filename.
+ returns: The loaded object, or null if the file could not be opened.
+ EndRem
+ Function Load:TVectorGfxObject(filename:String)
+ Local s:TStream=ReadStream(filename)
+
+ If Not s
+ Return Null
+ EndIf
+
+ s=LittleEndianStream(s)
+ Local o:TVectorGfxObject=New TVectorGfxObject
+
+ o.x=s.ReadInt()
+ o.y=s.ReadInt()
+ o.ang=s.ReadInt()
+
+ Local i:Int=s.ReadInt()
+
+ For Local f=0 Until i
+ o.AddLine(TVectorGfxLine.Load(s))
+ Next
+
+ s.Close()
+
+ Return o
+ End Function
+
+ Rem
+ bbdoc: Saves the object to the supplied @filename.
+ EndRem
+ Method Save(filename:String)
+ Local s:TStream=WriteStream(filename)
+
+ If Not s
+ Return Null
+ EndIf
+
+ s=LittleEndianStream(s)
+
+ s.WriteInt(x)
+ s.WriteInt(y)
+ s.WriteInt(ang)
+ s.WriteInt(lines.Count())
+
+ For Local l:TVectorGfxLine=EachIn lines
+ l.Save(s)
+ Next
+
+ s.Close()
+ End Method
+
+ Rem
+ bbdoc: Draw the object.
+ returns: A bitmask of collisions.
+ about: Draws the object. @colmap <u>cannot</u> be null - use a small collision map instead if you're uninterested in collisions
+ EndRem
+ Method Draw:Int(colmap:TVectorGfxCollisionMap)
+ Local col:Int=0
+ For Local l:TVectorGfxLine=EachIn lines
+ Local p1:TAlgoPoint=DoRotate(l.x1,l.y1,ang)
+ Local p2:TAlgoPoint=DoRotate(l.x2,l.y2,ang)
+
+ col:|Static.linedraw.draw(x+p1.x,y+p1.y,x+p2.x,y+p2.y,l.r,l.g,l.b,l.id,colmap)
+ Next
+
+ Return col
+ End Method
+End Type
+
+Rem
+bbdoc: Defines a line
+EndRem
+Type TVectorGfxLine
+ Field x1:Int
+ Field y1:Int
+ Field x2:Int
+ Field y2:Int
+ Field id:Int
+ Field r:Int
+ Field g:Int
+ Field b:Int
+
+ Rem
+ bbdoc: Create a line.
+ returns: The created line.
+ about: @x1, @y1, @x2 and @y2 are the co-ordinates of the line. @r, @g and @b is the line's colour. @id is the collision map mask for the line.
+ EndRem
+ Function Create:TVectorGfxLine(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int)
+ Local o:TVectorGfxLine=New TVectorGfxLine
+
+ o.x1=x1
+ o.y1=y1
+ o.x2=x2
+ o.y2=y2
+ o.r=r
+ o.g=g
+ o.b=b
+ o.id=id
+
+ Return o
+ End Function
+
+ Rem
+ bbdoc: This is for internal library use.
+ EndRem
+ Function Load:TVectorGfxLine(s:TStream)
+ Local o:TVectorGfxLine
+ o=New TVectorGfxLine
+ o.x1=s.ReadInt()
+ o.y1=s.ReadInt()
+ o.x2=s.ReadInt()
+ o.y2=s.ReadInt()
+ o.r=s.ReadInt()
+ o.g=s.ReadInt()
+ o.b=s.ReadInt()
+ o.id=s.ReadInt()
+ Return o
+ End Function
+
+ Rem
+ bbdoc: This is for internal library use.
+ EndRem
+ Method Save:TVectorGfxLine(s:TStream)
+ s.WriteInt(x1)
+ s.WriteInt(y1)
+ s.WriteInt(x2)
+ s.WriteInt(y2)
+ s.WriteInt(r)
+ s.WriteInt(g)
+ s.WriteInt(b)
+ s.WriteInt(id)
+ End Method
+End Type
+
+Private
+
+Type Static
+ Global linedraw:TVectorGfxLineStyle
+
+ Function Init()
+ linedraw=New LineSolid
+ End Function
+End Type
+
+Type LineSolid Extends TVectorGfxLineStyle
+ Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap)
+ Local mask:Int=0
+ Local lp:TList=DoLine(x1,y1,x2,y2)
+
+ SetColor(r,g,b)
+
+ For Local p:TAlgoPoint=EachIn lp
+ mask:|colmap.SetCollision(p.x,p.y,id)
+ Plot(p.x,p.y)
+ Next
+
+ Return mask
+ End Method
+End Type
+
+Type LineAlpha Extends TVectorGfxLineStyle
+ Field la:Double
+ Field ea:Double
+
+ Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap)
+ Local mask:Int=0
+ Local lp:TList=DoLine(x1,y1,x2,y2)
+ Local p:TAlgoPoint
+ Local a:Double=GetAlpha()
+
+ SetColor(r,g,b)
+ SetAlpha(ea)
+
+ p=TAlgoPoint(lp.RemoveFirst())
+
+ mask:|colmap.SetCollision(p.x,p.y,id)
+ Plot(p.x,p.y)
+
+ If lp.Count()=0
+ Return id
+ EndIf
+
+ p=TAlgoPoint(lp.RemoveLast())
+
+ mask:|colmap.SetCollision(p.x,p.y,id)
+ Plot(p.x,p.y)
+
+ SetAlpha(la)
+
+ For Local p:TAlgoPoint=EachIn lp
+ mask:|colmap.SetCollision(p.x,p.y,id)
+ Plot(p.x,p.y)
+ Next
+
+ SetAlpha(a)
+
+ Return mask
+ End Method
+End Type
+
+
+Type ThickAlpha Extends TVectorGfxLineStyle
+ Field a:Double
+
+ Method PlotPoint(x,y)
+ SetAlpha(a)
+ DrawLine(x-1,y-1,x+1,y-1,False)
+ DrawLine(x+1,y-1,x+1,y+1,False)
+ DrawLine(x+1,y+1,x-1,y+1,False)
+ DrawLine(x-1,y+1,x-1,y-1,False)
+ SetAlpha(1.0)
+ Plot(x,y)
+ End Method
+
+ Method Draw:Int(x1:Int, y1:Int, x2:Int, y2:Int, r:Int, g:Int, b:Int, id:Int, colmap:TVectorGfxCollisionMap)
+ Local mask:Int=0
+ Local lp:TList=DoLine(x1,y1,x2,y2)
+
+ SetColor(r,g,b)
+
+ For Local p:TAlgoPoint=EachIn lp
+ mask:|colmap.SetCollision(p.x,p.y,id)
+ PlotPoint(p.x,p.y)
+ Next
+
+ Return mask
+
+ End Method
+End Type
+
+Static.Init() \ No newline at end of file