Aviator on the BBC Micro

# Drawing lines: ClipBestEndOfLine

```       Name: ClipBestEndOfLine                                       [Show more]
Type: Subroutine
Category: Drawing lines
Summary: Clip a line at the start or end point, depending on which is best
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* DrawClippedLine (Part 4 of 6) calls ClipBestEndOfLine

Arguments:

(RR R)               The x-coordinate of the line's start point

(SS S)               The y-coordinate of the line's start point

TT                   The clipping requirements for the start point

(QQ W)               The x-coordinate of the line's end point

(H G)                The y-coordinate of the line's end point

UU                   The clipping requirements for the end point

Returns:

(RR R)               The x-coordinate of the line's new start point, clipped
to fit on-screen

(SS S)               The y-coordinate of the line's new start point, clipped
to fit on-screen

T                    Relative magnitude of line's vector |x-delta|

U                    Relative magnitude of line's vector |y-delta|

W                    Max/min x-coordinate for the new end of the line

G                    Max/min y-coordinate for the new end of the line

Other entry points:

AbortLine            Abort drawing this line

.ClipBestEndOfLine

LDA TT                 \ If TT and UU have a set bit in common, this means that
AND UU                 \ both points are off-screen in the same direction, so
BNE AbortLine          \ the line can't possibly cross the visible part of the
\ screen at any point, so jump to AbortLine to abort the
\ drawing of this line

LDA SS                 \ If the start point's y-coordinate is positive, jump to
BPL clen1              \ clen1 to skip the following instruction

EOR #&FF               \ Flip the start point's y-coordinate so it's positive,
\ so:
\
\   A = |start_y|

.clen1

STA maxCoord           \ Store the start point's y-coordinate in maxCoord, so:
\
\   maxCoord = |start_y|

LDA RR                 \ If the start point's x-coordinate is positive, jump to
BPL clen2              \ clen2 to skip the following instruction

EOR #&FF               \ Flip the start point's x-coordinate so it's positive,
\ so:
\
\   A = |start_x|

.clen2

CMP maxCoord           \ If the start point's x-coordinate is < maxCoord, jump
BCC clen3              \ to clen3 to skip the following instruction

STA maxCoord           \ The start point's x-coordinate is >= maxCoord, so
\ update maxCoord so it contains the maximum value:
\
\   maxCoord = max(|start_x|, |start_y|)

.clen3

LDA QQ                 \ If the end point's x-coordinate is positive, jump to
BPL clen4              \ clen4 to skip the following instruction

EOR #&FF               \ Flip the end point's x-coordinate so it's positive,
\ so:
\
\   A = |end_x|

.clen4

CMP maxCoord           \ If |end_x| >= maxCoord, the start point has a smaller
BCS ClipStartOfLine    \ x-coordinate magnitude which means it is closer to the
\ the start point, as it's a better candidate for
\ clipping

LDA H                  \ If the end point's y-coordinate is positive, jump to
BPL clen5              \ clen5 to skip the following instruction

EOR #&FF               \ Flip the end point's y-coordinate so it's positive,
\ so:
\
\   A = |end_y|

.clen5

CMP maxCoord           \ If |end_y| >= maxCoord, the start point has a smaller
BCS ClipStartOfLine    \ y-coordinate magnitude which means it is closer to the
\ the start point, as it's a better candidate for
\ clipping

JSR SwapLinePoints     \ Otherwise the end point is the better candidate for
\ clipping, so copy the end point's coordinates and
\ clipping information into the start point

LDA V                  \ We've just flipped the end point to the start, so flip
EOR #%11000000         \ bits 6 and 7 in V to reverse the line direction in
STA V                  \ both axes

JMP ClipStartOfLine    \ Jump to ClipStartOfLine to clip the line at the new
\ start point

.AbortLine

TSX                    \ Remove two bytes from the top of the stack, which
INX                    \ removes the return address that was put there by the
INX                    \ last JSR instruction. This means that the RTS below
TXS                    \ jumps two levels up the call stack, rather than one,