Revs on the BBC Micro

# Driving model: ApplyElevation (Part 1 of 5)

```       Name: ApplyElevation (Part 1 of 5)                            [Show more]
Type: Subroutine
Category: Driving model
Summary: Calculate changes in the car's elevation
Deep dive: The core driving model
Jumps and drops
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* ApplyDrivingModel calls ApplyElevation

Calculate the following:

* liftFromTorque = the lift of the front of the car caused by accelerating
or braking, in the range -5 to +3

A positive value of liftFromTorque means the horizon is drawn lower on the
screen, which means the nose is being pulled up.

The value of liftFromTorque is only changed if the car is on the ground. The
logic is as follows:

* Horizon goes down when we are not in reverse, we are applying the throttle
and engine torque is non-zero (i.e. we pull the nose of the car up by
by incrementing liftFromTorque, to a maximum of 3)

* Horizon goes up when we are not in reverse, we are applying the brakes and
we are moving (i.e. we push the nose of the car down by decrementing
liftFromTorque, to a minimum of -5)

* Otherwise, gradually bring the nose back to the normal level of zero, with
the value incrementing towards zero at twice the rate that it decrements
towards zero (so the nose rises at twice the speed that it falls, as the
suspension springs are more powerful than gravity)

.ApplyElevation

LDA heightAboveTrack   \ Set A = heightAboveTrack

DEC yJumpHeight        \ Set yJumpHeight = yJumpHeight - 2
DEC yJumpHeight

.elev1

\ If we get here then heightAboveTrack = 0 and A = 0

STA yJumpHeight        \ Set yJumpHeight = 0

STA yGravityDelta      \ Set yGravityDelta = 0

LDY liftFromTorque     \ Set Y = liftFromTorque

LDA gearNumber         \ If gearNumber = 0, then we are in reverse, so jump to
BEQ elev3              \ elev3

LDA throttleBrakeState \ If throttleBrakeState is negative, then there is no
BMI elev3              \ brake or throttle key press, so jump to elev3

BEQ elev2              \ If throttleBrakeState = 0, then the brakes are being

\ If we get here then the throttle is being applied

LDA engineTorque       \ Set A to the engine torque

BNE elev4              \ If the engine torque is non-zero, jump to elev4 to
\ increment the lift in Y

BEQ elev3              \ Jump to elev3 (this BEQ is effectively a JMP as A is
\ always zero)

.elev2

\ If we get here then we are not in reverse gear and the
\ brakes are being applied

LDA playerSpeedHi      \ Set A = playerSpeedHi

BNE elev5              \ If A is non-zero, then we are moving, so jump to elev5
\ to decrement the lift in Y

.elev3

\ This part of the routine brings the car nose back
\ towards the normal level, if it isn't there already
\
\ We get here when any of the following are true:
\
\   * In reverse
\
\   * Not in reverse, no brake or throttle key press
\
\   * Not in reverse, brakes are being applied, we are
\     not moving
\
\   * Not in reverse, no brakes, throttle is being
\     applied, engine torque is zero
\
\ In other words, we are not accelerating or braking, so
\ we slowly cancel any rise or fall of the car nose that
\ we may have applied previously, as follows:
\
\   * If the lift in Y is positive, we decrement it
\     towards zero via elev5
\
\   * If the lift in Y is negative, we increment it
\     towards zero and then increment it again via elev4
\
\ This means the list increments towards zero at twice
\ the rate that it decrements towards zero

TYA                    \ Set A = Y
\       = liftFromTorque

BEQ elev7              \ If liftFromTorque = 0, jump to elev7 to move on to
\ part 2 without updating liftFromTorque

BPL elev5              \ If liftFromTorque > 0, jump to elev5 to decrement the
\ lift in Y

\ If we get here then liftFromTorque < 0, so the nose of
\ the car is already being pushed up and the horizon is
\ lower than it would normally be

INY                    \ Set Y = Y + 1
\       = liftFromTorque + 1
\
\ So this pulls the nose of the car up, making the
\ horizon fall back towards the normal level

.elev4

\ This part of the routine pulls the nose of the car up
\ by incrementing Y (to a maximum of 3), making the
\ horizon fall
\
\ We jump here if we are not in reverse, we are applying
\ the throttle, and engine torque is non-zero

INY                    \ Set Y = Y + 1
\       = liftFromTorque + 1
\
\ So this pulls the nose of the car up, making the
\ horizon fall down

BMI elev6              \ If Y is negative, jump to elev6 to set liftFromTorque
\ to Y

CPY #4                 \ If Y < 4, jump to elev6 to set liftFromTorque = Y
BCC elev6

LDY #3                 \ Set Y = 3, so Y has a maximum value of 3

BCS elev6              \ Jump to elev6 (this BCS is effectively a JMP as we
\ just passed through a BCC)

.elev5

\ This part of the routine pushes the nose of the car
\ down by decrementing Y (to a minimum of -5), making
\ the horizon rise
\
\ We jump here if we are not in reverse, we are applying
\ the brakes, and we are moving

DEY                    \ Set Y = Y - 1
\
\ So this pushes the nose of the car down, making the
\ horizon rise up

BPL elev6              \ If Y is positive, jump to elev6 to set liftFromTorque
\ to Y

CPY #&FB               \ If Y >= -5, jump to elev6 to set liftFromTorque = Y
BCS elev6

LDY #&FB               \ Set Y = -5, so Y has a minimum value of -5

.elev6

STY liftFromTorque     \ Set liftFromTorque = Y
```