.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, \ jump to cras1 to crash into the fence \ 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) JMP SquealTyres \ Jump to SquealTyres to update spinYawAngle and make \ 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 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 subroutineName: 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 soundContext: See this subroutine in context in the source code References: This subroutine is called as follows: * MainDrivingLoop (Part 2 of 5) calls CheckForCrash
[X]
Subroutine Absolute8Bit (category: Maths (Arithmetic))
Calculate the absolute value (modulus) of an 8-bit number
[X]
Subroutine DrawFence (Part 1 of 2) (category: Screen buffer)
Draw the fence that we crash into when running off the track
[X]
Subroutine FlushSoundBuffers (category: Sound)
Flush all four specified sound buffers
[X]
Entry point MakeSound-3 in subroutine MakeSound (category: Sound)
Make the sound at the current volume level
[X]
Subroutine SquealTyres (category: Driving model)
Make the tyres squeal
[X]
Label cras1 is local to this routine
[X]
Label cras2 is local to this routine
[X]
Label cras3 is local to this routine
[X]
Variable crashedIntoFence (category: Car geometry)
Flag that records whether we have crashed into the fence
[X]
Variable edgeDistanceHi in workspace Zero page
High byte of the distance between the player's car and the nearest track edge
[X]
Variable edgeYawAngle in workspace Zero page
The yaw angle of the track segment that is closest to the player's car, from the point of view of the car
[X]
Variable engineStatus in workspace Zero page
Whether or not the engine is on
[X]
Variable heightAboveTrack in workspace Zero page
The car's height above the track, for when it is being dropped from the crane, or jumping from hitting the verge too fast
[X]
Variable horizonLine in workspace Zero page
The track line number of the horizon
[X]
Variable oddsOfEngineStart in workspace Zero page
The chances of the engine starting while revving the engine (the engine will start with a chance of 1 in oddsOfEngineStart)
[X]
Variable soundRevCount in workspace Zero page
The current pitch for the revs sound
[X]
Variable soundRevTarget in workspace Zero page
The target pitch for the revs sound
[X]
Variable spinYawAngleTop (category: Car geometry)
Top byte of the amount of yaw angle spin that is being applied to the player's car
[X]
Variable xPlayerSpeedHi (category: Driving model)
High byte of the x-coordinate of the velocity vector (i.e. x-axis speed) for the player's car during this main loop iteration
[X]
Variable yGravityDelta in workspace Zero page
The distance in the y-axis that the car would fall if the track wasn't there, for use when calculating the outcome of jumps and being dropped from the crane