.SetVergeBackground STX GG \ Set GG to the value passed in X STA U \ Set U to the index into the verge buffer DEC vergeBufferEnd \ Decrement the index of the last entry in the track \ verge buffer for the verge we are drawing LDA playerSideways \ If playerSideways < 40, then the player's car is CMP #40 \ facing along the track rather than sideways, so jump BCC sver8 \ to sver8 to join the loop below BCS sver9 \ If we get here then the player's car is facing \ sideways relative to the track direction, so jump to \ sver9 to skip the loop (this BCS is effectively a JMP \ as we just passed through a BCC) \ The following loop uses X as a loop counter to work \ through the verge buffer from entry U to the end, \ setting the background colour if the verge goes off \ the left of the screen .sver1 LDY yVergeRight,X \ If the pitch angle (i.e. the track line) of the X-th CPY #80 \ entry in the verge buffer is 80 or more, then it is BCS sver7 \ not on-screen, so jump to sver7 to move on to the next \ entry in the verge buffer LDA vergeDataRight,X \ If bit 7 of the X-th entry's vergeDataRight is set, BMI sver7 \ then this segment is hidden behind a hill, so jump to \ sver7 to move on to the next entry in the verge buffer LDA GG \ If GG = %00010100, which is the value we passed after CMP #%00010100 \ drawing the right verge, then jump to sver2 BEQ sver2 LDA xVergeRightHi+16,X \ Set W to the high byte of the yaw angle of the verge's STA W \ outer edge LDA xVergeRightHi,X \ Set A to the high byte of the yaw angle of the verge's \ inner edge JMP sver3 \ Jump to sver3 to keep going .sver2 LDA xVergeRightHi,X \ Set W to the high byte of the yaw angle of the verge's STA W \ inner edge LDA xVergeRightHi+16,X \ Set A to the high byte of the yaw angle of the verge's \ outer edge .sver3 \ At this point, W is the yaw angle of the leftmost \ verge edge, and A is the yaw angle of the rightmost \ verge edge, for the verge that we are drawing CLC \ Set A = A + 20 ADC #20 BMI sver7 \ If A is negative, jump to sver7 to move on to the next \ entry in the verge buffer LDA W \ Set A = W + 20 CLC ADC #20 BPL sver7 \ If A is positive, jump to sver7 to move on to the next \ entry in the verge buffer \ If we get to this point, then: \ \ * A + 20 is positive \ \ * W + 20 is negative \ \ Adding 20 degrees to the yaw angles will move them to \ the right by half the screen width, so this is the \ same as moving the angles from the left edge of the \ screen to the middle \ \ We then check whether moving the angles to the centre \ pushes the rightmost verge edge in A past the centre \ (i.e. positive), while still leaving the leftmost edge \ in the left half (i.e. negative) \ \ If so, then this means the verge is straddling the \ left edge of the screen, so we need to consider \ setting the background colour for this track line to \ the verge colour \ First, though, we need to skip forward through the \ verge buffer until we get to the next entry that is \ followed by a non-hidden entry (so this skips over \ any entries that are hidden behind hills) \ \ This ensures that we get to an entry in the verge \ buffer that has a verge colour, as hidden entries do \ not have a colour associated with them .sver4 LDA vergeDataRight+1,X \ If the next entry in the verge buffer is not hidden BPL sver5 \ behind a hill, jump to sver5 INX \ Increment X to point to the next entry in the verge \ buffer INC U \ Increment U to point to the next entry in the verge \ buffer CPX vergeBufferEnd \ If X < vergeBufferEnd then we haven't reached the end BCC sver4 \ of the verge buffer, so loop back to check the next \ entry .sver5 LDA backgroundColour,Y \ Set T to the current entry in the background colour STA T \ table for track line Y LDA backgroundColour,Y \ Set A to the current entry in the background colour \ table for track line Y BEQ sver6 \ If A = 0, then the background colour is currently \ set to black, so jump to sver6 to set the background \ colour to the verge colour AND #%00011100 \ Extract bits 2-4 of A, which contain the verge type in \ bits 3-4, and details in bit 2 of whether the colour \ was set by the SetVergeBackground routine CMP GG \ If A = GG, then bits 2-4 match the mask we passed to BEQ sver6 \ the routine, so jump to sver6 to set the background \ colour to the verge colour \ \ The possible values of GG are: \ \ * %000 00 1 00 (after drawing the left verge) \ \ * %000 10 1 00 (after drawing the right verge) \ \ So this jumps if we already set the background colour \ entry in this routine, and the verge type was \ leftVergeStart after drawing the left verge, or \ rightVergeStart after drawing the right verge \ If we get here then bits 2-4 of the current background \ colour do not match the mask in GG, so we have not \ already set this colour on this routine for the \ leftVergeStart or rightVergeStart verges ROR A \ Rotate the C flag into bit 7 of A, where: \ \ * C flag is clear if A < GG \ \ * C flag is set if A > GG EOR T \ If T and A have different values of bit 7, jump to BMI sver7 \ sver7 to move on to the next entry in the verge buffer \ Otherwise we fall through into sver6 to set the \ background colour to the verge colour .sver6 LDA vergeDataRight,X \ Set A to the verge data for the entry in the verge \ buffer that is crossing the left edge of the screen AND #%00000011 \ Extract the colour of the verge, which is in bits 0-1, \ so this is the colour that we want to store in the \ background colour table (as this is the colour of the \ verge mark that's at the left edge of the screen) ORA GG \ OR the verge colour with the mask that we passed to \ the routine, to give: \ \ * %000001xx (after drawing the left verge) \ \ * %000101xx (after drawing the right verge) \ \ where %xx is the colour of the verge STA backgroundColour,Y \ Store the result as the background colour for track \ line Y .sver7 INC U \ Increment the verge buffer index in U to move on to \ the next entry in the verge buffer .sver8 \ This is where we join the loop LDX U \ Set X to the loop counter in U, which contains the \ index of the entry to process in the verge buffer CPX vergeBufferEnd \ If X < vergeBufferEnd, jump back to sver1 to process BCC sver1 \ this entry .sver9 LDX vergeDepthOfField \ Set Y to the pitch angle (i.e. the track line) of the LDY yVergeRight,X \ entry in the verge buffer at the depth of field INY \ Increment the track line in Y RTS \ Return from the subroutineName: SetVergeBackground [Show more] Type: Subroutine Category: Drawing the track Summary: Update the background colour table for any verges that overlap the left edge of the screen Deep dive: Drawing the track vergesContext: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawTrack calls SetVergeBackground
This routine works through any track lines that might contain a verge, and checks whether the verge crosses the left edge of the screen, updating the relevant entry in the background colour table if it does.
Arguments: A Index of the first entry to check in the verge buffer, typically set to vergeDepthOfField so only entries that might contain a verge are checked X Set to a bit mask as follows: * %000 00 1 00 (after drawing the left verge) * %000 10 1 00 (after drawing the right verge) Only bits 2-4 of this are used
Returns: Y The track line just above the pitch angle of the segment at vergeDepthOfField (i.e. the furthest segment that might contain a verge)
[X]
Variable backgroundColour (category: Screen buffer)
The background colour for each track line
[X]
Variable playerSideways (category: Car geometry)
Contains the player's heading, for testing whether the car is pointing sideways
[X]
Label sver1 is local to this routine
[X]
Label sver2 is local to this routine
[X]
Label sver3 is local to this routine
[X]
Label sver4 is local to this routine
[X]
Label sver5 is local to this routine
[X]
Label sver6 is local to this routine
[X]
Label sver7 is local to this routine
[X]
Label sver8 is local to this routine
[X]
Label sver9 is local to this routine
[X]
Variable vergeBufferEnd in workspace Zero page
The index of the last entry in the track verge buffer for the side of the track we are currently drawing in DrawTrack
[X]
Variable vergeDataRight (category: Track geometry)
Data (such as colour) for the verge marks on the right side of the track
[X]
Variable vergeDepthOfField in workspace Zero page
The index into the verge buffer of the furthest verge mark, so for segments further from the player than this point, we do not draw verge marks
[X]
Variable xVergeRightHi (category: Track geometry)
High byte of segment yaw angles along the right track verge in front of the player (i.e. along the x-axis)
[X]
Variable yVergeRight (category: Track geometry)
Segment pitch angles along the right track verge in front of the player (i.e. along the up-down y-axis)