Revs on the BBC Micro

# Car geometry: CheckForCrash

```       Name: CheckForCrash                                           [Show more]
Type: Subroutine
Category: Car geometry
Summary: Check to see if we have crashed into the fence, and if so, display
the fence and make the crash sound
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* MainDrivingLoop (Part 2 of 5) calls CheckForCrash

.CheckForCrash

LDA edgeDistanceHi     \ If edgeDistanceHi < 2, then we are too close to the
CMP #2                 \ verge to have reached the fence or to spin out on the
BCC cras3              \ grass, so jump to cras3 to return from the subroutine

\ If we get here then we are quite far off the track

LDA edgeYawAngle       \ Set A to the yaw angle of the track segment that is
\ closest to the player's car, from the point of view of
\ the car

JSR Absolute8Bit       \ Set A = |A|
\       = |edgeYawAngle|

CMP #96                \ If A >= 96, then the nearest track segment to the
BCS cras1              \ player is within a cone stretching out behind the car
\ to 45 degrees on each side, so that's between -96 and
\ +96 in the following diagram:
\
\            0
\      -32   |   +32         Overhead view of car
\         \  |  /
\          \ | /             0 = looking straight ahead
\           \|/              +64 = looking sharp right
\   -64 -----+----- +64      -64 = looking sharp left
\           /|\
\          / | \
\         /  |  \
\      -96   |   +96
\           128
\
\ If the nearest track segment is behind us in this way,

\ If we get here then we have not hit the fence but we
\ are off the track, so we spin out

LDA #20                \ Set A = 20 so we apply a yaw angle spin of magnitude
\ 20 to the car

BIT spinYawAngleTop    \ Set the N flag according to the sign in bit 7 of
\ spinYawAngleTop, so the call to Absolute8Bit sets the
\ sign of A to the same sign as the spin yaw angle (so
\ the car spins out in the same direction as it is
\ currently spinning)

JSR Absolute8Bit       \ Set A = 20 * abs(spinYawAngle)

\ the tyres squeal, returning from the subroutine using
\ a tail call

.cras1

DEC crashedIntoFence   \ Decrement crashedIntoFence from 0 to &FF so the main
\ driving loop will pause while showing the fence

INC horizonLine        \ Increment horizonLine to simulate us ditching forward
\ into the fence (so the horizon goes up by a line)

JSR DrawFence          \ Draw the fence that we crash into when running off the
\ track

JSR FlushSoundBuffers  \ Flush all four sound channel buffers

LDA #4                 \ Make sound #4 (crash/contact) at the current volume
JSR MakeSound-3        \ level

LDA #0                 \ Set A = 0, so we can use it to reset variables to zero
\ in the following loop

LDX #30                \ We now zero all 30 variable bytes from xPlayerSpeedHi
\ to xSteeringForceHi, so so set up a loop counter in X

.cras2

STA xPlayerSpeedHi,X   \ Zero the X-th byte from xPlayerSpeedHi

DEX                    \ Decrement the loop counter

BPL cras2              \ Loop back until we have zeroed all variables from
\ xPlayerSpeedHi to xSteeringForceHi

STA engineStatus       \ Set engineStatus = 0 to turn off the engine

STA yGravityDelta      \ Set yGravityDelta = 0 to cancel the effect of gravity
\ on the car

STA soundRevCount      \ Set soundRevCount = 0 to stop the engine sound

STA soundRevTarget     \ Set soundRevTarget = 0 to stop the engine sound

LDA #127               \ Set heightAboveTrack = 127 so the car is dropped from
STA heightAboveTrack   \ this height by the crane (if this is a Novice race, in
\ which case it restarts without calling ResetVariables,
\ which otherwise would zero heightAboveTrack)

LDA #31                \ Set oddsOfEngineStart = 31 to make it harder to
STA oddsOfEngineStart  \ restart the engine (with a 1 in 32 chance)

.cras3

RTS                    \ Return from the subroutine
```