Skip to navigation

Revs on the BBC Micro

Drawing the track: DrawVergeEdge

Name: DrawVergeEdge [Show more] Type: Subroutine Category: Drawing the track Summary: Draw one of the four track verge edges into the screen buffer Deep dive: Drawing the track verges
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawTrack calls DrawVergeEdge

Arguments: A The index in the verge buffer where we start drawing the track verges (so this is essentially the depth of field for this verge) Y Determines the type of verge that we are drawing: * 0 = leftVergeStart, the left edge of the left verge * 1 = leftTrackStart, the right edge of the left verge * 2 = rightVergeStart, the left edge of the right verge * 3 = rightGrassStart, the right edge of the right verge vergeBufferEnd The index of the last entry in the track verge buffer for the side of the track we are currently drawing pixelMaskVerge Offset within the vergePixelMask table for segments that are close enough to show a verge * 0 for leftVergeStart * 8 for leftTrackStart * 16 for rightVergeStart * 28 for rightGrassStart pixelMaskNoVerge Offset within the vergePixelMask table for segments that are too far away to show a verge * n/a for leftVergeStart * 0 for leftTrackStart * 28 for rightVergeStart * 28 for rightGrassStart MM Set to 0, to act as the low byte of (NN MM) R Set to 0, to act as the low byte of (S R) P Set to &80, to use as the low byte of (Q P)
.DrawVergeEdge STY vergeType \ Set vergeType to the type of verge that we are \ going to draw STA prevPitchIndex \ Set prevPitchIndex to the verge buffer index in A, to \ use as the starting index into the buffer for the \ drawing process CMP vergeBufferEnd \ If A >= vergeBufferEnd, then it points to an index BCS vedg6 \ after the end of the verge buffer data for this side \ of the track, so jump to vedg6 to return from the \ subroutine CLC \ Set: ADC vergeEdgeInOut,Y \ STA prevYawIndex \ prevYawIndex = A + vergeEdgeInOut \ \ for the type of verge we are drawing \ \ This sets prevYawIndex to the following: \ \ * A for the inner edges of the verge mark in \ leftTrackStart and rightVergeStart \ \ * A + 16 for the outer edges of the verge mark in \ leftVergeStart and rightGrassStart \ \ This points prevYawIndex to the correct part of the \ track segment list for this entry in the buffer, as \ the angles for the outer edge of the verge mark are \ stored 16 bytes after the inner edge angles (the inner \ edge angles are in bytes 6 to 21 of the track segment \ list, while the outer edge angles are in bytes 22 to \ 37) LDA vergeTableHi,Y \ Modify the following instructions at verl2 and verb2, STA verl2+2 \ depending on the type of verge in Y: STA verb2+2 \ LDA vergeTableLo,Y \ * 0 = STA &7000,Y -> STA leftVergeStart,Y STA verl2+1 \ * 1 = STA &7000,Y -> STA leftTrackStart,Y STA verb2+1 \ * 2 = STA &7000,Y -> STA rightVergeStart,Y \ * 3 = STA &7000,Y -> STA rightGrassStart,Y \ \ So this modifies the DrawVergeByteLeft and \ DrawVergeByteRight routines to draw the verge \ specified in Y LDX prevYawIndex \ Set X = prevYawIndex, to use as the index to the \ verge's yaw angles LDY prevPitchIndex \ Set Y = prevPitchIndex, to use as the index to the \ verge's pitch angles SEC \ Set the C flag to pass to DrawSegmentEdge so it does \ not draw the edge (as this is the first call for this \ edge so we just set up the variables, ready for the \ next call) JSR DrawSegmentEdge \ Draw the verge edge for this entry (i.e. this segment) \ in the verge buffer .vedg1 INX \ Increment X to the index of the next yaw angle in the \ track segment list INY \ Increment Y to the index of the next pitch angle in \ the track segment list CPY vergeBufferEnd \ If Y >= vergeBufferEnd then we have processed all the BCS vedg6 \ entries in the verge buffer, so jump to vedg6 to \ return from the subroutine LDA vergeDataRight,Y \ If bit 7 is set in vergeDataRight for the new segment BMI vedg1 \ from the track segment list, then this segment is \ hidden behind a hill, so jump to vedg1 move on to the \ next segment LDA prevPitchIndex \ If prevPitchIndex < vergeDepthOfField, then the new CMP vergeDepthOfField \ segment is further away from the player than the depth BCC vedg2 \ of field index in vergeDepthOfField, so jump to vedg2 \ to draw the track edges without verge marks BNE vedg3 \ If prevPitchIndex <> vergeDepthOfField, which means \ prevPitchIndex > vergeDepthOfField, jump to vedg3 \ If we get here then prevPitchIndex = vergeDepthOfField \ so the current segment is right at the point where we \ stop drawing verge marks LDA vergeDataRight-1,Y \ Set A to the colour of the previous entry in the verge AND #3 \ buffer, which is stored in bits 0-2 of vergeDataRight \ (the -1 points to the previous entry, which will be \ one step further away from the player) \ \ The colour values are: \ \ * 0 = black \ * 1 = red \ * 2 = white BNE vedg4 \ If the verge of the previous entry is red or white, \ jump to vedg4 to set A = pixelMaskVerge + A * 4 and \ draw the edge \ If we get here then the verge of the previous entry \ is black STY vergeDepthOfField \ Set Y = vergeDepthOfField SEC \ Set the C flag to pass to DrawSegmentEdge so it does \ not draw the edge LDA vergeType \ Set A to the type of verge we are drawing BEQ vedg5 \ If we are drawing leftVergeStart, jump to vedg5 with \ the C flag set and A = 0 to draw the edge .vedg2 \ If we get here then one of these is true: \ \ * prevPitchIndex < vergeDepthOfField, so the current \ segment is further away from the player than the \ depth of field index in vergeDepthOfField, so we \ draw all verge marks as black \ \ * prevPitchIndex = vergeDepthOfField and the \ previous segment's verge edge is red or white and \ we are not drawing leftVergeStart, so we want to \ draw a black verge mark \ \ In both cases we want to draw black verge marks LDA pixelMaskNoVerge \ Set A = pixelMaskNoVerge \ \ pixelMaskNoVerge always points to a pixel byte that's \ green and black, so is this how we draw the track for \ segments that are beyond the verge depth of field CLC \ Set the C flag to pass to DrawSegmentEdge so it draws \ the edge BCC vedg5 \ Jump to vedg5 with the C flag clear and A set to \ pixelMaskNoVerge to draw the edge (this BCC is \ effectively a JMP as the C flag is always clear) .vedg3 \ If we get here then prevPitchIndex > vergeDepthOfField \ so the current segment is closer to the player than \ the depth of field index in vergeDepthOfField, so we \ draw the verge mark LDA vergeDataRight-1,Y \ Set A to the colour of the previous entry in the verge AND #3 \ buffer, which is stored in bits 0-2 of vergeDataRight \ (the -1 points to the previous entry, which will be \ one step further away from the player) \ \ The colour values are: \ \ * 0 = black \ * 1 = red \ * 2 = white BNE vedg4 \ If the verge of the previous entry is red or white, \ jump to vedg4 to set: \ \ * A = pixelMaskVerge + 4 for red \ \ * A = pixelMaskVerge + 8 for white \ \ And then pass this to DrawSegmentEdge LDA vergeType \ Set A to the type of verge we are drawing CMP #1 \ If we are drawing leftTrackStart, jump to vedg5 with BEQ vedg5 \ the C flag set and A = 1, so it doesn't draw the edge \ but just sets up the variables CMP #2 \ If we are drawing rightVergeStart, jump to vedg5 with BEQ vedg5 \ the C flag set and A = 2, so it doesn't draw the edge \ but just sets up the variables LDA #0 \ Set A = 0, so we pass A = pixelMaskVerge to \ DrawSegmentEdge .vedg4 ASL A \ Set A = pixelMaskVerge + A * 4 ASL A \ CLC \ This also clears the C flag, so the call to ADC pixelMaskVerge \ DrawSegmentEdge draws the verge edge .vedg5 JSR DrawSegmentEdge \ Draw the verge edge for this entry (i.e. this segment) \ in the verge buffer STY prevPitchIndex \ Update the value of prevPitchIndex to point to the \ entry we just processed, which is now the previous \ entry STX prevYawIndex \ Update the value of prevYawIndex to point to the entry \ we just processed, which is now the previous entry JMP vedg1 \ Loop back to vedg1 to process the next entry .vedg6 RTS \ Return from the subroutine