Skip to navigation


Driving model: ApplyElevation (Part 2 of 5)

Name: ApplyElevation (Part 2 of 5) [Show more] Type: Subroutine Category: Driving model Summary: Calculate the player's heading and sideways flag 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: * playerHeading, which is the player's yaw angle, relative to the direction of the track, where a heading of 0 means the player is pointing straight along the track * playerSideways, which contains the following information: * If playerSideways < 40, then the player's car is facing forwards or backwards along the track * If playerSideways >= 40, then the player's car is facing sideways, relative to the direction of the track
.elev7 LDX playerSegmentIndex \ Set X to the number of the player's track segment from \ the track segment buffer LDY segmentVector,X \ Fetch the segment vector number for track segment X, \ which gives us the number of the segment vector for \ the track segment containing the player LDA playerPitchAngle \ Set V = playerPitchAngle STA V LDA xTrackSegmentI,Y \ Store the sign of the segment vector's x-coordinate EOR zTrackSegmentI,Y \ multiplied by the segment vector's z-coordinate on the PHP \ stack, i.e. xTrackSegmentI * zTrackSegmentI LDA zTrackSegmentI,Y \ Set A to the segment vector's z-coordinate in \ zTrackSegmentI PHP \ Store the sign of zTrackSegmentI on the stack JSR Absolute8Bit \ Set A = |A| \ = |zTrackSegmentI| CMP #60 \ Store the comparison of |zTrackSegmentI| and 60 on the PHP \ stack BCC elev8 \ If |zTrackSegmentI| < 60, jump to elev8 LDA xTrackSegmentI,Y \ Set A to the segment vector's x-coordinate JSR Absolute8Bit \ Set A = |A| \ = |xTrackSegmentI| .elev8 STA T \ Set T = A \ = |zTrackSegmentI| if |zTrackSegmentI| < 60 \ |xTrackSegmentI| if |zTrackSegmentI| >= 60 LSR A \ Set A = (A / 2 + T) / 4 CLC \ = (A / 2 + A) / 4 ADC T \ = A * 3 / 8 LSR A LSR A PLP \ Pull the result of the comparison of |zTrackSegmentI| \ and 60 from the stack BCS elev9 \ If |zTrackSegmentI| >= 60, jump to elev9 EOR #%00111111 \ We know bits 6 and 7 of A are clear, as we just \ shifted A to the right twice, so this flips bits 0 to \ 5, so the range 0 to 63 gets flipped around to 63 to 0 .elev9 PLP \ Pull the sign of zTrackSegmentI from the stack BPL elev10 \ If zTrackSegmentI is positive, jump to elev10 EOR #%10000000 \ Flip the bit 7 of A, so the range 0 to 63 gets \ changed to -65 to -128 .elev10 PLP \ Pull the sign of xTrackSegmentI * zTrackSegmentI from \ the stack JSR Absolute8Bit \ Set the sign of A to the sign of xTrackSegmentI * \ zTrackSegmentI SEC \ Set A = A - playerYawAngleHi SBC playerYawAngleHi STA playerHeading \ Set playerHeading = A \ A is an angle that represents the player's heading, \ relative to the current segment, like this: \ \ 0 \ -32 | +32 Overhead view of car \ \ | / \ \ | / 0 = looking straight ahead \ \|/ +64 = looking sharp right \ -64 -----+----- +64 -64 = looking sharp left \ /|\ \ / | \ \ / | \ \ -96 | +96 \ 128 \ \ An angle of 0 means our car is facing forwards along \ the track, while an angle of +32 means we are facing \ 45 degrees to the right of straight on, and an angle \ of 128 means we are facing backwards along the track BPL elev11 \ If A is positive, jump to elev11 to skip the following EOR #&FF \ Invert A, so this effectively reflects the angle into \ the right half of the above diagram: \ \ 0 \ | 32 \ | / \ | / \ |/ \ +----- 64 \ |\ \ | \ \ | \ \ | 96 \ 127 .elev11 CMP #64 \ If A < 64, then the player's heading is forwards, so BCC elev12 \ jump to elev12 EOR #%01111111 \ A >= 64, so the player's heading is backwards and in \ the bottom-right quadrant, so flip bits 0-6 of A, \ changing the range of the bottom-right quadrant from \ 64 to 127 to 63 to 0, to give this: \ \ 0 \ | 32 \ | / \ | / \ |/ \ +----- 63 \ |\ \ | \ \ | \ \ | 32 \ 0 \ \ If the value in A is greater than 40, then we are \ looking sideways compared to the track direction, and \ conversely, if A is less than 40, we are looking \ forwards or backwards .elev12 STA playerSideways \ Store the value of A in playerSideways, so we can test \ whether the player is facing sideways on the track