Skip to navigation

Revs on the BBC Micro

Drawing the track: DrawShallowToLeft

Name: DrawShallowToLeft [Show more] Type: Subroutine Category: Drawing the track Summary: Draw a verge edge with a shallow gradient from right to left Deep dive: Drawing the track verges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawSegmentEdge (Part 6 of 7) calls DrawShallowToLeft

Arguments: X The pixel number to start drawing from, in the range 0 to 7, as it is measured across the two edge bytes that we draw in this routine Y The track line to draw on (0 to 79) SS The scaled yaw delta along the edge to draw TT The scaled pitch delta along the edge to draw RR The pitch angle of the current segment (we stop drawing the edge when Y reaches this value) UU The number of the dash data block where we start drawing JJ The right pixel byte when drawing the edge in the screen buffer, i.e. the fill byte to the right of the edge (S R) Address of the first dash data block in the memory page containing the pixels at the start of the previous edge (Q P) Address of the second dash data block in the memory page containing the pixels at the start of the previous edge (NN MM) Address of the third dash data block in this sequence, i.e. the first memory page of the next dash data block
.DrawShallowToLeft LDA jumpShallowLeft,X \ Modify the BCC instruction at shrl1 below so that STA shrl1+1 \ it jumps to the destination given in the X-th entry in \ the jumpShallowLeft lookup table LDX #128 \ Set X = 128, so we can detect at the end of the \ routine whether X has been altered (which only happens \ if we draw something) LDA SS \ Set A = -SS EOR #&FF \ CLC \ This is the starting value for the cumulative slope ADC #1 \ error, which we tally up in A CLC \ Clear the C flag so the next instruction effectively \ becomes a JMP .shrl1 BCC shrl2 \ This instruction was modified above, so it jumps to \ the address specified in the jumpShallowLeft table, as \ follows: \ \ * shrl19 when X = 0 \ * shrl17 when X = 1 \ * shrl15 when X = 2 \ * shrl13 when X = 3 \ * shrl10 when X = 4 \ * shrl8 when X = 5 \ * shrl6 when X = 6 \ * shrl4 when X = 7 \ \ These jump-points start by drawing a pixel byte before \ moving on to the slope error calculations \ \ The following entry points are also supported, though \ these don't appear to be used, as the routine is only \ called with X in the range 0 to 7: \ \ * shrl18 when X = 8 \ * shrl16 when X = 9 \ * shrl14 when X = 10 \ * shrl12 when X = 11 \ * shrl9 when X = 12 \ * shrl7 when X = 13 \ * shrl5 when X = 14 \ * shrl3 when X = 15 \ \ These jump-points start with the slope error \ calculations rather than a call to the draw routine, \ they would presumably omit the first pixel byte of the \ line, were they to be used .shrl2 LDX #128 \ Set X = 128, so we can detect at the end of the \ routine whether X has been altered (which only happens \ if we draw something) .shrl3 \ We start with the slope error calculation for pixel 3 \ of the second dash data block ADC TT \ Set A = A + TT, to add the pitch delta to the slope \ error BCC shrl5 \ If the addition didn't overflow, skip to the next \ pixel to step along the x-axis, as the cumulative \ pitch deltas haven't yet added up to a multiple of SS \ If we get here then the pitch deltas have added up to \ a whole line and the addition has overflowed, so we \ need to draw a pixel SBC SS \ If we get here then the cumulative pitch deltas in TT \ have added up to a multiple of the yaw delta in SS, so \ we subtract SS from the slope error (which we can do \ as we know the C flag is set) .shrl4 LDX #3 \ Draw the edge in pixel 3 of the second dash data block JSR DrawVergeByteRight \ (the rightmost pixel) and draw a fill byte in the \ third dash data block \ \ If we have reached the pitch angle of the current \ segment, then we have reached the end of the edge to \ draw, in which case DrawVergeByteRight will jump to \ StopDrawingEdge to abort this edge and return us two \ routines up the call stack, to DrawSegmentEdge .shrl5 ADC TT \ Repeat the slope error calculation for pixel 2 BCC shrl7 \ of the second dash data block SBC SS .shrl6 LDX #2 \ Draw the edge in pixel 2 of the second dash data block JSR DrawVergeByteRight \ (the third pixel) and draw a fill byte in the third \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge .shrl7 ADC TT \ Repeat the slope error calculation for pixel 1 BCC shrl9 \ of the second dash data block SBC SS .shrl8 LDX #1 \ Draw the edge in pixel 1 of the second dash data block JSR DrawVergeByteRight \ (the second pixel) and draw a fill byte in the third \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge .shrl9 ADC TT \ Repeat the slope error calculation for pixel 0 BCC shrl11 \ of the second dash data block SBC SS .shrl10 LDX #0 \ Draw the edge in pixel 0 of the second dash data block JSR DrawVergeByteRight \ (the leftmost pixel) and draw a fill byte in the third \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge .shrl11 JSR DrawGrassRight \ If nothing has been drawn in the second dash data \ block (in which case X will still be 128), then fill \ the byte with green grass DEC UU \ Decrement UU so we now draw in the left pair of dash \ data blocks (i.e. the first and second dash data \ blocks of the three that we set up) .shrl12 ADC TT \ Repeat the slope error calculation for pixel 3 BCC shrl14 \ of the first dash data block SBC SS .shrl13 LDX #3 \ Draw the edge in pixel 3 of the first dash data block JSR DrawVergeByteLeft \ (the rightmost pixel) and draw a fill byte in the \ second dash data block, or abort the drawing and \ return to DrawSegmentEdge if we've finished drawing \ the edge .shrl14 ADC TT \ Repeat the slope error calculation for pixel 2 BCC shrl16 \ of the first dash data block SBC SS .shrl15 LDX #2 \ Draw the edge in pixel 2 of the first dash data block JSR DrawVergeByteLeft \ (the third pixel) and draw a fill byte in the second \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge .shrl16 ADC TT \ Repeat the slope error calculation for pixel 1 BCC shrl18 \ of the first dash data block SBC SS .shrl17 LDX #1 \ Draw the edge in pixel 1 of the first dash data block JSR DrawVergeByteLeft \ (the second pixel) and draw a fill byte in the second \ dash data block, or abort the drawing and return to \ DrawSegmentEdge if we've finished drawing the edge .shrl18 ADC TT \ Repeat the slope error calculation for pixel 0 BCC shrl20 \ of the first dash data block SBC SS .shrl19 LDX #0 \ Draw the edge in pixel 0 of the first dash data block JSR DrawVergeByteLeft \ (the leftmost pixel) and draw a fill byte in the \ second dash data block, or abort the drawing and \ return to DrawSegmentEdge if we've finished drawing \ the edge .shrl20 JSR DrawGrassLeft \ If nothing has been drawn in the first dash data \ block (in which case X will still be 128), then fill \ the byte with green grass DEC S \ Decrement S to move (S R) on to the previous page, to \ move it left by two dash data blocks DEC Q \ Decrement Q to move (Q P) on to the previous page, to \ move it left by two dash data blocks DEC NN \ Decrement NN to move (NN MM) on to the previous page, \ to move it left by two dash data blocks DEC UU \ Decrement UU to the number of the previous dash data \ block to the left LDX S \ If (S R) hasn't yet reached the leftmost dash data CPX #HI(dashData0)-1 \ block (i.e. it hasn't gone past block 0, which is at CLC \ the left edge of the screen), then jump back to shrl2 BNE shrl2 \ to keep drawing (with the C flag cleared, as it gets \ set by the comparison) JMP strl10 \ Jump to strl10 to finish drawing the right-hand pixel \ byte of the pair, as the first dash data block in \ (S R) might be off-screen, but the second one in (Q P) \ isn't