ASL A \ Set (W A) = (0 A) << 2 ROL W \ = (W A) << 2 ASL A \ = heightAboveTrack << 2 ROL W \ = heightAboveTrack * 4 STA V \ Set (W V) = (W A) \ = heightAboveTrack * 4 LDX currentPlayer \ Set X to the driver number of the current player LDA carProgress,X \ Set A to the lowest byte of the player's progress \ through the current segment JSR MultiplyHeight \ Set: \ \ A = A * yTrackSegmentI \ = carProgress * yTrackSegmentI \ \ flipping the sign if we are facing backwards \ \ The value given in yTrackSegmentI is the y-coordinate \ of the segment vector, i.e. the vector from this \ segment to the next, which is the same as the change \ in height as we move through the segment \ \ The calculation above effectively works out the \ difference in elevation of the car as it progresses \ through the segment, and puts it in A BPL elev19 \ If A is positive, jump to elev19 to skip the following \ instruction DEC W \ A is negative, so set W = W - 1 .elev19 LDY playerSegmentIndex \ Set Y to the index of the player's track segment from \ the track segment buffer CLC \ Set: ADC ySegmentCoordILo,Y \ \ A = A + ySegmentCoordILo \ = carProgress * yTrackSegmentI + ySegmentCoordILo \ \ ySegmentCoordILo is the low byte of the 3D \ y-coordinate for the player's track segment \ \ So A now contains the segment's y-coordinate, plus the \ elevation of the car due to the track's progress \ through the segment PHP \ Store the C flag on the stack, which will be set if \ the addition just overflowed CLC \ Set A = A + 172 ADC #172 PHP \ Store the C flag on the stack, which will be set if \ the addition just overflowed \ We now calculate the following for the y-coordinate of \ the player's 3D coordinates: \ \ (yPlayerCoordTop yPlayerCoordHi) \ \ = A \ + (W V) \ + (ySegmentCoordIHi 0) \ + C flag from the first addition \ + C flag from the second addition \ \ = carProgress * yTrackSegmentI + ySegmentCoordILo \ + 172 \ + heightAboveTrack * 4 \ + (ySegmentCoordIHi 0) \ + C flag from the first addition \ + C flag from the second addition \ \ = carProgress * yTrackSegmentI \ + 172 \ + heightAboveTrack * 4 \ + (ySegmentCoordIHi ySegmentCoordILo) \ \ with all the correct carry bits included CLC \ We start with the low bytes ADC V STA yPlayerCoordHi LDA ySegmentCoordIHi,Y \ And then the high bytes ADC W PLP ADC #0 PLP ADC #0 STA yPlayerCoordTop LDA playerSpeedHi \ Set U = playerSpeedHi, which is the player's speed in STA U \ mph LDA #33 \ Set A = 33 JSR Multiply8x8 \ Set (A T) = A * U \ = playerSpeedHi * 33 \ \ So A = playerSpeedHi * 33 / 256 ASL U \ Set A = A + U * 2 CLC \ = playerSpeedHi * 33 / 256 + playerSpeedHi * 2 ADC U \ = playerSpeedHi * 2.13 STA carSpeedHi,X \ Set carSpeedHi for the player's car to playerSpeedHi * \ 2.13 \ \ carSpeedHi is now the speed of the car in terms of \ 1/256-ths of a segment, with 120 mph in playerSpeedHi \ corresponding to a whole segment in carSpeedHi (as \ 120 * 2.13 = 255) RTS \ Return from the subroutineName: ApplyElevation (Part 5 of 5) [Show more] Type: Subroutine Category: Driving model Summary: Calculate the player's 3D y-coordinate and progress speed Deep dive: The core driving model Jumps and dropsContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
Calculate the following: * (yPlayerCoordTop yPlayerCoordHi) = (ySegmentCoordIHi ySegmentCoordILo) + carProgress * yTrackSegmentI + heightAboveTrack * 4 + 172 * carSpeedHi for the player's car = playerSpeedHi * 2.13
[X]
Subroutine Multiply8x8 (category: Maths (Arithmetic))
Calculate (A T) = T * U
[X]
Subroutine MultiplyHeight (category: Track geometry)
Multiply the height above ground of a specified track segment by A
[X]
Variable carProgress in workspace Stack variables
Lowest byte of each car's progress through the segment it's in
[X]
Variable carSpeedHi in workspace Stack variables
High byte of each car's forward speed
[X]
Variable currentPlayer in workspace Zero page
The number of the current player
[X]
Label elev19 is local to this routine
[X]
Variable playerSegmentIndex in workspace Zero page
Used to store the index * 3 of the track segment containing the player's car in the track segment buffer
[X]
Variable playerSpeedHi in workspace Zero page
High byte of the speed of the player's car along the track
[X]
Variable yPlayerCoordHi (category: Car geometry)
The high byte of the y-coordinate of the player's 3D coordinates
[X]
Variable yPlayerCoordTop (category: Car geometry)
The top byte of the y-coordinate of the player's 3D coordinates
[X]
Variable ySegmentCoordIHi in workspace Main variable workspace
The high byte of the 3D y-coordinate for an inner track segment in the track segment buffer
[X]
Variable ySegmentCoordILo in workspace Main variable workspace
The low byte of the 3D y-coordinate for an inner track segment in the track segment buffer