.ProcessOvertaking LDX currentPosition \ Set X to the current player's position, to use as a \ loop counter in the following as we work backwards \ through the field from this position .tact1 STX W \ Store the position number in W, so we can retrieve it \ during the loop LDA driversInOrder,X \ Set T to the number of the driver in position X STA T JSR GetPositionAhead \ Set X to the number of the position ahead of position \ X LDA driversInOrder,X \ Set G to the number of the driver in position X, i.e. \ the number of the driver ahead of driver T STX G \ Store the position number of the driver ahead in G, so \ we can retrieve it during the loop TAY \ Set Y to the number of the driver ahead of driver T LDX T \ Set X to the number of the driver we are currently \ processing \ So in the following, we are applying driving tactics \ to driver X (aka driver T) \ \ We start by comparing driver X with the driver ahead, \ driver Y \ \ Drivers X and Y are in positions W and G respectively LDA #0 \ Set N = 0, which we will use to build the car status STA N \ flags for driver X STA carSteering,X \ Set this driver's carSteering to 0, so by default \ driver X will drive straight (though we may change \ this below) JSR CompareCarSegments \ Set A to the number of segments between drivers X and \ Y (i.e. the race distance between the cars) BCS tact4 \ If the C flag is set then the cars are far apart, so \ jump to tact18 via tact4 to update the car status byte \ for driver X to N = 0, and then move on to the next \ driver BPL tact5 \ If the distance in A is positive then driver Y is \ still ahead of driver X, so jump to tact5 to apply \ tactics to driver X in part 2 \ If we get here then driver Y is not actually in front \ of this driver, despite being in a higher position, so \ we now need to check how far ahead driver X is CMP #&F6 \ If A < -10, driver X is not very far ahead of driver BCC tact4 \ Y, so we don't yet consider this a passing move, so \ jump to tact18 via tact4 to update the car status byte \ for driver X to N = 0, and then move on to the next \ driver \ If we get here then driver X has overtaken driver Y, \ and the distance between the cars is >= 10, so we need \ to swap their positions, as driver X has pulled far \ enough away for this to be considered a passing move LDX W \ Swap the drivers between positions W and G, i.e. swap LDY G \ the positions of driver X and Y, so driver X moves JSR SwapDriverPosition \ into a higher position, and set: \ \ * X = the number of the driver now at position W, \ i.e. the driver behind, previously referred to \ as driver Y \ \ * Y = the number of the driver now at position G, \ i.e. the driver ahead, previously referred to \ as driver X \ \ So now X and Y have swapped, so driver Y just passed \ driver X SEC \ Set bit 7 of updateDriverInfo so the driver names get ROR updateDriverInfo \ updated at the top of the screen, to reflect the new \ race positions CPY currentPlayer \ If driver Y (the one that just did the overtaking) BNE tact2 \ is not the current player, jump to tact2 to skip the \ following two instructions \ If we get here then the C flag is set, as the above \ comparison is equal \ Driver Y (the one that just did the overtaking) is the \ current player, so we now need to reduce the current \ player's position by 1 to move them into a higher \ position LDA #&99 \ Set A = -1 in BCD, which we can use to decrement the \ BCD number in positionChangeBCD below, so the current \ player's position will go down by 1 BNE tact3 \ Jump to tact3 (this BNE is effectively a JMP as A is \ never zero) .tact2 CPX currentPlayer \ If driver X (the one that just got overtaken) is not BNE tact4 \ the current player, jump to tact18 via tact4 to update \ the car status byte for this driver to N = 0, and then \ move on to the next driver \ If we get here then the C flag is set, as the above \ comparison is equal \ Driver Y (the one that just did the overtaking) is the \ current player, so we now need to reduce the current \ player's position by 1 to move them into a higher \ position LDA #&01 \ Set A = 1 in BCD, which we can use to increment the \ BCD number in positionChangeBCD below, so the current \ player's position will go up by 1 .tact3 STA T \ Set T = A, so A contains the position change in BCD LDA driverLapNumber,Y \ Set A to the lap number for the driver ahead ROL H \ Rotate the C flag into bit 0 of H, which we know is \ set from the comparisons above, so this rotates a 1 \ into bit 0 of H (though this doesn't appear to be used \ anywhere, so this instruction is a bit of a mystery) SBC driverLapNumber,X \ Subtract the lap number for this driver BNE tact4 \ If the drivers are on different laps, jump to tact18 \ via tact4 to update the car status byte for this \ driver to N = 0, and then move on to the next driver SED \ Set the D flag to switch arithmetic to Binary Coded \ Decimal (BCD) CLC \ Set positionChangeBCD = positionChangeBCD + T LDA T \ ADC positionChangeBCD \ so this applies the position change we calculated STA positionChangeBCD \ above to positionChangeBCD CLD \ Clear the D flag to switch arithmetic to normal .tact4 JMP tact18 \ Jump to tact18 to update the car status byte for \ driver X to N = 0, and then move on to the next driverName: ProcessOvertaking (Part 1 of 3) [Show more] Type: Subroutine Category: Tactics Summary: Process all cars for overtaking manoeuvres, checking first to see if the car has just finished overtaking the car in front Deep dive: Tactics of the non-player driversContext: See this subroutine in context in the source code References: This subroutine is called as follows: * FinishRace calls ProcessOvertaking * MoveAndDrawCars calls ProcessOvertaking
Returns: H Gets a 1 rotated left into bit 0 each time we process one car overtaking another
[X]
Subroutine CompareCarSegments (category: Car geometry)
Calculate the distance between two cars, in terms of segments and progress with the current segment
[X]
Subroutine GetPositionAhead (category: Drivers)
Decrement X to the previous position number (from 19 to 0 and round again), which gives the position ahead of X
[X]
Subroutine SwapDriverPosition (category: Drivers)
Swap the position for two drivers (i.e. overtake)
[X]
Variable carSteering in workspace Stack variables
Contains the steering to apply to each car
[X]
Variable currentPlayer in workspace Zero page
The number of the current player
[X]
Variable currentPosition in workspace Zero page
The position of the current player
[X]
Variable driverLapNumber in workspace Main variable workspace
The current lap number for each driver
[X]
Variable driversInOrder in workspace Stack variables
A list of driver numbers in order
[X]
Variable positionChangeBCD in workspace Zero page
The change in BCD for the player's race position
[X]
Label tact18 in subroutine ProcessOvertaking (Part 3 of 3)
[X]
Label tact2 is local to this routine
[X]
Label tact3 is local to this routine
[X]
Label tact4 is local to this routine
[X]
Label tact5 in subroutine ProcessOvertaking (Part 2 of 3)
[X]
Variable updateDriverInfo (category: Text)
Flag that controls whether the driver names are updated in the information block at the top of the screen