Revs on the BBC Micro

# Driving model: ApplyElevation (Part 4 of 5)

```       Name: ApplyElevation (Part 4 of 5)                            [Show more]
Type: Subroutine
Category: Driving model
Summary: Calculate the height of the car above the track
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:

* yGravityDelta = max(yGravityDelta - 4, -56)

* If the car falls past ground level, calculate the following to make the
car bounce upwards by half the rate that it's falling:

* yGravityDelta = |yGravityDelta| / 2

* yJumpHeight = |yGravityDelta| / 4

* spinYawAngleHi = spinYawAngleHi >> 1 with bit 7 set

* heightAboveTrack = 1

and make the crash/contact sound, otherwise set:

heightAboveTrack = heightAboveTrack + yGravityDelta

and clip the result to the range 0 to 127

LDA #0                 \ Set W = 0, to use as the high byte of (W A) below
STA W

LDA yGravityDelta      \ Set A = yGravityDelta - 4
SEC                    \
SBC #4                 \ This applies the effect of gravity on the car, which
\ makes the car fall faster all the time that it's
\ falling

BVC elev14             \ The overflow flag is set if yGravityDelta is negative
LDA #&C8               \ but the result is positive, in which case we set
\ A = -56, so this sets a minimum value for A of -56:
\
\   A = max(yGravityDelta - 4, -56)

.elev14

STA yGravityDelta      \ Set yGravityDelta = A
\                   = max(yGravityDelta - 4, -56)

CLC                    \ Set A = A + heightAboveTrack
ADC heightAboveTrack   \       = max(yGravityDelta - 4, -56) + heightAboveTrack

BVS elev17             \ The overflow flag is set if:
\
\   * yGravityDelta + heightAboveTrack > 127
\     and both are < 128
\     (i.e. adding two positives gives a negative)
\
\   * yGravityDelta + heightAboveTrack < 128
\     and both are > 127
\     (i.e. adding two negatives gives a positive)
\
\ heightAboveTrack = 127

BPL elev18             \ If A is positive, jump to elev18 to set
\ heightAboveTrack = A

.elev15

LDA yGravityDelta      \ Set A = yGravityDelta

JSR Absolute8Bit       \ Set A = |A|
\       = |yGravityDelta|

CMP #5                 \ If A < 5, jump to elev16 to set heightAboveTrack = 0
BCC elev16

\ If we get here then the car has fallen past ground
\ level, so we need to bounce it upwards

JSR ApplyBounce        \ Calculate the following to make the car bounce upwards
\ by half the rate that it's falling:
\
\   yGravityDelta = |yGravityDelta| / 2
\
\   yJumpHeight = |yGravityDelta| / 4
\
\   heightAboveTrack = heightAboveTrack + 1
\
\   spinYawAngleHi = spinYawAngleHi >> 1 with bit 7 set
\
\ and make the crash/contact sound

LDA #1                 \ Set A = 1, to use as the value of heightAboveTrack,
\ overriding the calculation we just did

BNE elev18             \ Jump to elev18 (this BNE is effectively a JMP as A is
\ never zero)

.elev16

LDA #0                 \ Set A = 0, to use as the value of heightAboveTrack

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

.elev17

LDA #127               \ Set A = 127, to use as the value of heightAboveTrack

.elev18

STA heightAboveTrack   \ Store the value of A in heightAboveTrack
```