Skip to navigation

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 \ origin, so jump to ClipStartOfLine to clip the line at \ 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 \ origin, so jump to ClipStartOfLine to clip the line at \ 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, \ so we return to the subroutine that called the \ subroutine that called ClipBestEndOfLine. The only \ call to ClipBestEndOfLine is in the DrawClippedLine \ routine, and the only call to DrawClippedLine is in \ DrawCanopyView, so this ensures that the RTS below \ returns us to to DrawCanopyView without drawing the \ line and without leaving anything on the stack \ \ In short, this makes the RTS abort the drawing of this \ line RTS \ Return to the DrawCanopyView routine