.dver11 LDA GG \ Set A to bits 6 and 7 of GG AND #%11000000 BEQ dver12 \ If bits 6 and 7 of GG are clear, then both this \ segment's verge edge and the previous segment's verge \ edge were on-screen, so jump to dver12 \ If we get here then either this segment's verge edge \ or the previous segment's verge edge was off-screen \ \ We also set bit 7 of VV above to the following: \ \ * Bit 7 is clear if this yaw angle >= previous yaw \ angle \ \ * Bit 7 is set if this yaw angle < previous yaw \ angle \ \ with these flipped if vergeOnScreenEdge is &FF, which \ means the edge is partially on-screen \ \ So bit 7 is set if: \ \ * The edge is not partially on-screen and this yaw \ angle < previous yaw angle, in which case we have \ just moved left, falling off the left edge of the \ screen \ \ * The edge is partially on-screen and this yaw \ angle >= previous yaw angle, in which case we have \ just moved right onto the screen from the left \ edge \ \ In either case we are drawing over the left edge of \ the screen, so we need will need to update the \ background colour for this track line LDA VV \ Set A to bit 7 of VV to store in updateBackground, so AND #%10000000 \ A is non-zero if we are drawing on the left edge of \ the screen .dver12 STA updateBackground \ Store A in updateBackground, so we update the \ background colour table in the StopDrawingEdge routine \ We set WW above to the previous edge's pitch angle \ minus this edge's pitch angle, so it is positive if \ the edge is heading up the screen, negative if it is \ heading down the screen LDA WW \ If WW is non-zero, jump to dver13 BNE dver13 \ If we get here then this edge and the previous edge \ have the same pitch angle LDA vergeOnScreenEdge \ Set WW = ~vergeOnScreenEdge EOR #&FF \ STA WW \ So WW is 0 if the edge is partially on-screen, or &FF \ otherwise .dver13 \ We now modify both the DrawVergeByteLeft and \ DrawVergeByteRight routines so they do nothing on \ entry, and either increment or decrement Y on exit, \ depending on the polarity of WW \ \ We modify the routines as follows: \ \ * If WW is positive, so the edge is heading up the \ screen, then do NOP on entry and INY on exit, so \ we increase the track line as we draw the edge \ \ * If WW is negative, so the edge is heading down the \ screen, then do NOP on entry and DEY on exit, so \ we decrease the track line as we draw the edge \ \ This ensures that when we call these routines, they \ increase or decrease the track line in the appropriate \ direction for the line we are drawing BPL dver14 \ If WW is positive, jump to dver14 LDA #&88 \ Set A to the opcode for the DEY instruction BNE dver15 \ Jump to dver15 (this BNE is effectively a JMP as A is \ never zero) .dver14 LDA #&C8 \ Set A to the opcode for the INY instruction .dver15 STA verl5 \ Modify the instructions at verl5 and verb5 as follows: STA verb5 \ \ * INY when WW is positive \ \ * DEY when WW is negative \ \ So the track line in Y increases when WW is positive \ and the line is heading up the screen LDA #&EA \ Set A to the opcode for the NOP instruction STA verl1 \ Modify the instruction at verl1 to NOP, so the \ DrawVergeByteLeft routine doesn't update Y on entry STA verb1 \ Modify the instruction at verb1 to NOP, so the \ DrawVergeByteRight routine doesn't update Y on entry LDY pixelMaskIndex \ Set Y = pixelMaskIndex so we can use it to fetch the \ correct pixel bytes from vergePixelMask for this edge LDX #0 \ We are about to populate four bytes in objectPalette \ and vergeEdgeRight, so set X as a loop counter that \ starts at 0 \ \ We populate objectPalette with the four bytes at \ offset Y in vergePixelMask, and vergeEdgeRight with \ the same bytes, but masked to only include the \ rightmost 4, 3, 2 and 1 pixels \ \ This means the objectPalette table actually contains \ pixel bytes at this point, rather than full colour \ four-pixel bytes as it does in the rest of the code, \ but we can still think of it as containing the \ "palette" for the track verges, it's just a more \ sophisticated palette - stripey toothpaste is still \ toothpaste, after all .dver16 LDA vergePixelMask,Y \ Set A to the Y-th verge pixel mask in vergePixelMask STA objectPalette,X \ Store the full pixel mask in objectPalette AND pixelsEdgeRight,X \ Store the pixel mask in vergeEdgeRight, with all the STA vergeEdgeRight,X \ pixels to the right of position X set, plus pixel X INY \ Increment Y so we fetch the next verge pixel mask INX \ Increment X so we store in the next byte of four CPX #4 \ Loop back until we have populated all four bytes BNE dver16Name: DrawSegmentEdge (Part 3 of 7) [Show more] Type: Subroutine Category: Drawing the track Summary: Modify the drawing routines according to the edge gradient Deep dive: Drawing the track vergesContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
This part modifies the edge-drawing routines for the verge so they move in the right directions depending on the signs of the deltas calculated previously, and set up pixel bytes and masks for the correct colour scheme depending on which verge edge is being drawn.
[X]
Label dver12 is local to this routine
[X]
Label dver13 is local to this routine
[X]
Label dver14 is local to this routine
[X]
Label dver15 is local to this routine
[X]
Label dver16 is local to this routine
[X]
Variable objectPalette (category: 3D objects)
The object colour palette that maps logical colours 0 to 3 to physical colours
[X]
Variable pixelMaskIndex in workspace Zero page
The index into the vergePixelMask table for the colour of the verge edge we are drawing in DrawSegmentEdge
[X]
Variable pixelsEdgeRight (category: Drawing pixels)
Pixel byte with all the pixels to the right of position X set, plus pixel X
[X]
Variable updateBackground in workspace Zero page
Flag to indicate we have changed the background colour of a track line
[X]
Label verb1 in subroutine DrawVergeByteRight
[X]
Label verb5 in subroutine DrawVergeByteRight
[X]
Variable vergeEdgeRight (category: Drawing the track)
Contain the four pixel bytes for the verge edge we are drawing, masked to only include the rightmost 4, 3, 2 and 1 pixels
[X]
Variable vergeOnScreenEdge in workspace Zero page
Determines whether the verge edge we are drawing for the current segment is partially off-screen
[X]
Variable vergePixelMask (category: Drawing the track)
Pixel bytes for drawing track verge edges
[X]
Label verl1 in subroutine DrawVergeByteLeft
[X]
Label verl5 in subroutine DrawVergeByteLeft