Skip to navigation

Revs on the BBC Micro

Drawing the track: SetVergeBackground

Name: 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 verges
Context: 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)
.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 subroutine