.BuildVisibleCar LDA driversInOrder,X \ Set A to the number of the driver in position X STA thisDriver \ Store the driver number in thisDriver so we can \ retrieve it later STA objectNumber \ Store the driver number in objectNumber, in case we \ need to hide this driver's car below TAX \ Set X to the driver number LDY #23 \ Set Y to 23, the object number we use to store the \ front segment of the track segment buffer SEC \ Set the C flag for a 16-bit calculation in the call \ to CompareSegments JSR CompareSegments \ Set A and T to the distance between driver X and \ the front segment in the track segment buffer in \ object Y BCS bvis1 \ If the C flag is set then the two cars are far apart, \ i.e. |T| < 128, so jump to bvis1 to hide the car EOR directionFacing \ This tests whether bit 7 of directionFacing and bit 7 BMI bvis1 \ of the distance in A are different, which will happen \ if either of the following is true: \ \ * We are facing forwards (0) and driver X is ahead \ of the front segment in the track segment buffer \ (1) \ \ * We are facing backwards (1) and driver X is not \ ahead of the front segment in the track segment \ buffer (0) \ \ In both cases driver X is too far away from us to be \ seen, and bit 7 of the result of the EOR will be set, \ so jump to bvis1 to hide the car LDA T \ Set T = |T| JSR Absolute8Bit \ STA T \ so A and T contain the absolute value of the distance \ between the car and the front segment in the track \ segment buffer CMP #40 \ If |A| < 40, jump to bvis2 to skip the following BCC bvis2 \ instruction and continue creating the car object \ If we get here then the car and the front segment in \ the track segment buffer are far apart, so we hide the \ car .bvis1 JMP HideObject \ Hide the object in objectNumber, which hides the car \ object for driver X, and return from the subroutine \ using a tail call .bvis2 \ If we get here, A and T contain the absolute value of \ the distance between the car and the front segment in \ the track segment buffer ASL A \ Set A = A * 2 \ = distance * 2 CLC \ Set A = ~(A + T) ADC T \ = ~(distance * 2 + distance) EOR #&FF \ = ~(distance * 3) SEC \ Set A = A + 1 + frontSegmentIndex ADC frontSegmentIndex \ = ~(distance * 3) + 1 + frontSegmentIndex \ = -(distance * 3) + frontSegmentIndex \ = frontSegmentIndex - distance * 3 \ \ frontSegmentIndex contains the index * 3 of the front \ segment in the track segment buffer, so this is the \ same as: \ \ (front segment index - distance) * 3 BPL bvis3 \ If the result was positive, i.e. track segment index \ > distance, jump to bvis3 to skip the following CLC \ Otherwise set A = A + 120 ADC #120 .bvis3 TAY \ Copy the result from A into Y, so Y now contains the \ track segment index * 3 of the track segment for the \ car object LDA carStatus,X \ If bit 4 of driver X's carStatus is set, then tactics AND #%00010000 \ are not enabled for this car, so jump to BNE BuildCarObjects \ BuildCarObjects to skip setting the car's steering LDA carSpeedHi,X \ If the high byte of driver X's speed is less than 50, CMP #50 \ jump to BuildCarObjects BCC BuildCarObjects LDA segmentSteering,Y \ Set the driver's carSteering to the segmentSteering STA carSteering,X \ value for this track segment, so the car follows the \ curve of the trackName: BuildVisibleCar [Show more] Type: Subroutine Category: 3D objects Summary: Check the distance to the specified car and build the car object if it is close enough Deep dive: Tactics of the non-player driversContext: See this subroutine in context in the source code References: This subroutine is called as follows: * MoveAndDrawCars calls BuildVisibleCar
Arguments: X The position of the driver whose distance we want to check
[X]
Subroutine Absolute8Bit (category: Maths (Arithmetic))
Calculate the absolute value (modulus) of an 8-bit number
[X]
Subroutine BuildCarObjects (Part 1 of 3) (category: 3D objects)
Calculate the 3D coordinate of the specified car
[X]
Subroutine CompareSegments (category: 3D objects)
Calculate the distance between two objects, in terms of the difference in their segment numbers
[X]
Subroutine HideObject (category: 3D objects)
Set an object to be hidden
[X]
Label bvis1 is local to this routine
[X]
Label bvis2 is local to this routine
[X]
Label bvis3 is local to this routine
[X]
Variable carSpeedHi in workspace Stack variables
High byte of each car's forward speed
[X]
Variable carStatus in workspace Stack variables
Each car's status byte
[X]
Variable carSteering in workspace Stack variables
Contains the steering to apply to each car
[X]
Variable directionFacing in workspace Zero page
The direction that our car is facing
[X]
Variable driversInOrder in workspace Stack variables
A list of driver numbers in order
[X]
Variable frontSegmentIndex in workspace Zero page
Used to store the index * 3 of the front track segment in the track segment buffer
[X]
Variable objectNumber in workspace Zero page
The object number of the four-part car we are drawing
[X]
Variable segmentSteering in workspace Main variable workspace
The carSteering value to steer round the corner for a track segment in the track segment buffer
[X]
Variable thisDriver in workspace Zero page
The number of the car we are currently drawing