Skip to navigation

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 * DrawRadarBlip 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)