' This is a higher level method that builds the Int values to pass to CreateCustomCharacter in the shapes array
' Create the value to draw a line in a custom character
' The line starts at X0,Y0 and ends at X1,Y1
Public Sub CreateLine(x0 As Int, y0 As Int, x1 As Int, y1 As Int) As Int
Dim line As Int = 0
line = line + Bit.ShiftLeft(Bit.And(0xf,x0), 24)
line = line + Bit.ShiftLeft(Bit.And(0x1f,y0), 16)
line = line + Bit.ShiftLeft(Bit.And(0xf,x1), 8)
line = line + Bit.And(0x1f,y1)
Return line
End Sub
' This is a higher level method that builds the Int values to pass to CreateCustomCharacter in the shapes array
' Create the value to draw a circle in a custom character
' The circle is centred on X1,Y1 and the quadrants to draw are bit ORed together
' UpperRight = 0x1, LowerRight = 0x2, LowerLeft = 0x4, Upper Left = 0x8
Public Sub CreateCircle(radius As Int, quadrants As Int, x1 As Int, y1 As Int, fill As Boolean) As Int
Dim circle As Int = 0x20000000
If fill Then circle = circle + 0x80000000
circle = circle + Bit.ShiftLeft(radius, 24)
circle = circle + Bit.ShiftLeft(quadrants, 16)
circle = circle + Bit.ShiftLeft(x1, 8)
circle = circle + y1
Return circle
End Sub
' This is a higher level method that builds the Int values to pass to CreateCustomCharacter in the shapes array
' Create the value to draw a triangle in a custom character
' The triangles corners are at X0,Y0 X1,Y1 and X2,Y2
Public Sub CreateTriangle(x0 As Int, y0 As Int, x1 As Int, y1 As Int, x2 As Int, y2 As Int, fill As Boolean) As Int
Dim triangle As Int = 0x30000000
If fill Then triangle = triangle + 0x80000000
triangle = triangle + Bit.ShiftLeft(Bit.And(0xf,x0), 24)
triangle = triangle + Bit.ShiftLeft(Bit.And(0x1f,y0), 16)
triangle = triangle + Bit.ShiftLeft(Bit.And(0xf,x1), 8)
triangle = triangle + Bit.And(0x1f,y1)
triangle = triangle + Bit.ShiftLeft(Bit.And(0xf,x2), 12) ' extra X
triangle = triangle + Bit.ShiftLeft(Bit.And(0x7,y2), 5) ' extra Y lsbits * 3
triangle = triangle + Bit.ShiftLeft(Bit.And(0x18,y2), 18) ' extra Y msbits * 2
Return triangle
End Sub
' This is a higher level method that builds the Int values to pass to CreateCustomCharacter in the shapes array
' Create the value to draw a box in a custom character
' The box top left start is X0,Y0 and bottom right is X1,Y1
Public Sub CreateBox(x0 As Int, y0 As Int, x1 As Int, y1 As Int, fill As Boolean) As Int
Dim box As Int = 0x10000000
If fill Then box = box + 0x80000000
box = box + Bit.ShiftLeft(Bit.And(0xf,x0), 24)
box = box + Bit.ShiftLeft(Bit.And(0x1f,y0), 16)
box = box + Bit.ShiftLeft(Bit.And(0xf,x1), 8)
box = box + Bit.And(0x1f,y1)
Return box
End Sub
'-----------------------------------------
' Private custom character drawing methods
'-----------------------------------------
Private Sub PlotTriangle(x0 As Int, y0 As Int, x1 As Int, y1 As Int, x2 As Int, y2 As Int, points(,) As Byte, Fill As Int)
' This is a pretty crude algorithm, but it is simple, works and it isn't invoked often
PlotLine(x0, y0, x1, y1, points)
PlotLine(x1, y1, x2, y2, points)
PlotLine(x2, y2, x0, y0, points)
If Fill > 0 Then
FillTriangle(x0, y0, x1, y1, x2, y2, points)
End If
End Sub
Private Sub FillTriangle(x0 As Int, y0 As Int, x1 As Int, y1 As Int, x2 As Int, y2 As Int, points(,) As Byte)
' first sort the three vertices by y-coordinate ascending so v0 Is the topmost vertice */
Dim tx, ty As Int
If y0 > y1 Then
tx = x0 : ty = y0
x0 = x1 : y0 = y1
x1 = tx : y1 = ty
End If
If y0 > y2 Then
tx = x0 : ty = y0
x0 = x2 : y0 = y2
x2 = tx : y2 = ty
End If
If y1 > y2 Then
tx = x1 : ty = y1
x1 = x2 : y1 = y2
x2 = tx : y2 = ty
End If
Dim dx0, dx1, dx2 As Double
Dim x3, x4, y3, y4 As Double
Dim inc As Int
If y1 - y0 > 0 Then dx0=(x1-x0)/(y1-y0) Else dx0=0
If y2 - y0 > 0 Then dx1=(x2-x0)/(y2-y0) Else dx1=0
If y2 - y1 > 0 Then dx2=(x2-x1)/(y2-y1) Else dx2=0
x3 = x0 : x4 = x0
y3 = y0 : y4 = y0
If dx0 > dx1 Then
While
Do While y3 <= y1
If x3 > x4 Then inc = -1 Else inc = 1
For x = x3 To x4 Step inc
points(x, y3) = 1
Next
y3 = y3 + 1 : y4 = y4 + 1 : x3 = x3 + dx1 : x4 = x4 + dx0
Loop
x4=x1
y4=y1
Do While y3 <= y2
If x3 > x4 Then inc = -1 Else inc = 1
For x = x3 To x4 Step inc
points(x ,y3) = 1
Next
y3 = y3 + 1 : y4 = y4 + 1 : x3 = x3 + dx1 : x4 = x4 + dx2
Loop
Else
While
Do While y3 <= y1
If x3 > x4 Then inc = -1 Else inc = 1
For x = x3 To x4 Step inc
points(x, y3) = 1
Next
y3 = y3 + 1 : y4 = y4 + 1 : x3 = x3 + dx0 : x4 = x4 +dx1
Loop
x3=x1
y3=y1
Do While y3<=y2
If x3 > x4 Then inc = -1 Else inc = 1
For x = x3 To x4 Step inc
points(x, y3) = 1
Next
y3 = y3 + 1 : y4 = y4 + 1 : x3 = x3 + dx2 : x4 = x4 + dx1
Loop
End If
End Sub
Private Sub PlotBox(x0 As Int, y0 As Int, x1 As Int, y1 As Int, points(,) As Byte, Fill As Int)
' This is a pretty crude algorithm, but it is simple, works and itsn't invoked often
PlotLine(x0, y0, x0, y1, points)
PlotLine(x0, y0, x1, y0, points)
PlotLine(x1, y0, x1, y1, points)
PlotLine(x0, y1, x1, y1, points)
If Fill > 0 Then
For x = x0 To x1
PlotLine(x, y0, x, y1, points)
Next
End If
End Sub
Private Sub PlotCircle(radius As Int, quadrants As Int, x1 As Int, y1 As Int, points(,) As Byte, fill As Int)
' This is a pretty crude algorithm, but it is simple, works and itsn't invoked often
Dim mask As Int = 1
For q = 3 To 0 Step -1
If Bit.And(quadrants, mask) <> 0 Then
For i = q*90 To q*90+90 Step 1
Dim x,y As Double
x = x1 - SinD(i)*radius
y = y1 - CosD(i)*radius
If fill > 0 Then
PlotLine(x1, y1, x, y, points)
Else
points(Round(x), Round(y)) = 1
End If
Next
End If
mask = Bit.ShiftLeft(mask, 1)
Next
End Sub
' Bresenham's line algorithm - see Wikipedia
Private Sub PlotLine(x0 As Int, y0 As Int, x1 As Int, y1 As Int, points(,) As Byte )
If Abs(y1 - y0) < Abs(x1 - x0) Then
If x0 > x1 Then
PlotLineLow(x1, y1, x0, y0, points)
Else
PlotLineLow(x0, y0, x1, y1, points)
End If
Else
If y0 > y1 Then
PlotLineHigh(x1, y1, x0, y0, points)
Else
PlotLineHigh(x0, y0, x1, y1, points)
End If
End If
End Sub
Private Sub PlotLineHigh(x0 As Int, y0 As Int, x1 As Int, y1 As Int, points(,) As Byte )
Dim dx As Int = x1 - x0
Dim dy As Int = y1 - y0
Dim xi As Int = 1
If dx < 0 Then
xi = -1
dx = -dx
End If
Dim D As Int = 2*dx - dy
Dim x As Int = x0
For y = y0 To y1
points(x,y) = 1
If D > 0 Then
x = x + xi
D = D - 2*dy
End If
D = D + 2*dx
Next
End Sub
Private Sub PlotLineLow(x0 As Int, y0 As Int, x1 As Int,y1 As Int, points(,) As Byte )
Dim dx As Int = x1 - x0
Dim dy As Int = y1 - y0
Dim yi As Int = 1
If dy < 0 Then
yi = -1
dy = -dy
End If
Dim D As Int = 2*dy - dx
Dim y As Int = y0
For x = x0 To x1
points(x,y) = 1
If D > 0 Then
y = y + yi
D = D - 2*dx
End If
D = D + 2*dy
Next
End Sub