Skip to navigation


Driving model: ApplyElevation (Part 5 of 5)

Name: 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 drops
Context: 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
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 subroutine