# 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

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

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

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

\ 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

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
```