Aviator on the BBC Micro

# Drawing lines: DrawVectorLine (Part 1 of 3)

```       Name: DrawVectorLine (Part 1 of 3)                            [Show more]
Type: Subroutine
Category: Drawing lines
Summary: Draw a line: set up pixel bytes and slope variables
Deep dive: Line buffers
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* DrawFuelPixel calls DrawVectorLine
* DrawIndicatorLine calls DrawVectorLine
* DrawOrthoLine calls DrawVectorLine

Draw/erase a line from (I, J) as a vector (T, U) with direction V.

This routine uses Bresenham's algorithm to draw the line, by working along the
longer axis of the line vector, one pixel at a time, plotting a pixel after
each step. All the while we keep a cumulative tally of fractional pixel counts
along the shorter axis (known as the "slope error"), and move one pixel along
the shorter axis when the tally reaches a multiple of the axis length.

Arguments:

I                    Start point x-coordinate

J                    Start point y-coordinate, relative to the bottom of the
canopy/top of the dashboard. Specifically:

* J = 0 to 151 are all within the bounds of the canopy

* The bottom pixel inside the canopy is 0, while the
top pixel just below the top canopy edge is 151

* J = -1 to -96 are all on the dashboard

* The white horizontal edge at the bottom of the
canopy/top of the dashboard is -1

* The bottom row of pixels on-screen is -96

N                    Drawing mode:

* Bit 7 clear = draw

* Bit 7 set = erase

T                    Magnitude of x-coordinate of line's vector |x-delta|
Horizontal width/length of line when V = 0

U                    Magnitude of y-coordinate of line's vector |y-delta|
Vertical width/length of line when V = 0

V                    Direction of vector (T, U):

* Bit 7 is the direction of the x-delta

* Bit 6 is the direction of the y-delta

Direction is like a clock, so positive (clear) is up and
right

.DrawVectorLine

LDY #3                 \ Set Y = 3 to use as a byte counter in the following
\ loop, so it writes four bytes

LDA #%00010001         \ Set A = %00010001, the pixel pattern for pixel 0 in
\ white

.dvec1

STA RR,Y               \ Set the Y-th byte of RR to A

ASL A                  \ Set A = A * 2

DEY                    \ Decrement the byte counter

BPL dvec1              \ Loop back until we have updated RR to RR+3 as
\ follows:
\
\   RR   = %10001000 = pixel 3 in white
\   RR+1 = %01000100 = pixel 2 in white
\   RR+2 = %00100010 = pixel 1 in white
\   RR+3 = %00010001 = pixel 0 in white

LDA #0                 \ Set QQ = 0
STA QQ

STA PP                 \ Set PP = 0

LDA T                  \ If T < U, jump down to dvec2 to skip the following
CMP U                  \ two instructions
BCC dvec2

\ If we get here then T >= U, so the line is a shallow
\ horizontal slope

STA VV                 \ Set VV = T, the length of the longer axis

BCS dvec11             \ Jump down to dvec11 to start drawing the line (this
\ BCS is effectively a JMP as we just passed through a
\ BCC)

.dvec2

\ If we get here then T < U, so the line is a steep
\ vertical slope

LDA U                  \ Set VV = U, the length of the longer axis
STA VV

STA PP                 \ Set PP = U

BCC dvec11             \ Jump down to dvec11 to start drawing the line (this
\ BCC is effectively a JMP as we got here by taking a
\ BCC)
```