Skip to navigation

Aviator on the BBC Micro

Flight model: ApplyAerodynamics (Part 2 of 3)

Name: ApplyAerodynamics (Part 2 of 3) [Show more] Type: Subroutine Category: Flight model Summary: Check whether the plane is stalling, and if it is, simulate one wing stalling before the other, and make the stalling sound Deep dive: The flight model Stalling and recovery
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

This part does the following: * If we are already stalling and not going fast enough to pull out of the stall, make the stalling sound and move on * If we are not already stalling, or we are possibly going fast enough to pull out of the stall (zVelocityPHi >= 11), we perform the stall check: zVelocityP <= |yVelocityP| * 4 If this is true, then we are stalling. * If we have just started stalling (i.e. we weren't already stalling but we are now), check that we are not too close to the ground (yPlaneLo >= 20), and assuming we aren't, apply a roll to the plane to simulate one of the wings stalling before the other: zTurn = zTurn +/- (A 0) >> 5 where: * The +/- sign is the sign of yTurn * A = xTurnTop EOR #%00111111 * Set the force factor for yLiftDrag according to the stalling state.
\ In the following, we jump to aero9 to make the \ stalling beep if both of these are true: \ \ * The force factor for yLiftDrag = 39, which \ indicates that we are already stalling \ \ * zVelocityPHi < 11, which indicates that the \ forward speed of the plane is too low to pull us \ out of the current stall \ \ In other words, if we are already stalling and the \ speed is not yet high enough to stop the stall, we \ jump straight to the part of the routine that makes \ the stalling sound LDA forceFactor+4 \ If the force factor for yLiftDrag <> 39, skip the CMP #39 \ following three instructions as we are not currently BNE aero6 \ stalling LDA zVelocityPHi \ If zVelocityPHi < 11, jump to aero9 as the plane is CMP #11 \ stalling BCC aero9 .aero6 \ If we get here then we are either not stalling, or we \ are already stalling but are possibly going fast \ enough to pull out of the stall, so we now perform the \ stalling check \ \ The plane stalls if this is true: \ \ zVelocityP <= |yVelocityP| * 4 \ \ in other words, when the plane is moving forwards at \ less than a quarter of the speed at which it is moving \ up or down, we stall \ \ When we first stall, then the plane rolls slightly to \ simulate one of the wings stalling before the other \ (though this is skipped if the plane is flying very \ low, at less than 20 feet above the ground) \ \ A reminder that we set the following in part 1: \ \ (J I) = |yVelocityP| * 4 \ \ We now compare the two 16-bit values in (J I) and \ zVelocityP, by first comparing the high bytes, and if \ they are equal, comparing the low bytes \ \ If it turns out that (J I) < zVelocityP, we jump to \ aero10 to maintain normal flight, so that's when: \ \ |yVelocityP| * 4 < zVelocityP \ \ but if (J I) >= zVelocityP, we are stalling, so that's \ when: \ \ zVelocityP <= |yVelocityP| * 4 LDA J \ If J < zVelocityPHi, then (J I) < zVelocityP, so jump CMP zVelocityPHi \ to aero10 to maintain normal flight BCC aero10 BNE aero7 \ If J <> zVelocityPHi, i.e. J > zVelocityPHi, then \ (J I) > zVelocity so jump to aero7 as we are going \ slowly enough to stall \ If we get here then J = zVelocityPHi, so now we \ compare the low bytes LDA I \ If I < zVelocityPLo, then (J I) < zVelocityP, so jump CMP zVelocityPLo \ to aero10 to maintain normal flight BCC aero10 .aero7 \ If we get here then (J I) >= zVelocityP, so: \ \ zVelocityP <= |yVelocityP| * 4 \ \ which means we are stalling \ \ We now check the plane's height above the ground in \ yPlane, as we don't roll the plane if it is less than \ 20 feet from the ground (probably as this would kill \ us instantly as the wings hit the ground, which would \ be a bit unfair, even if this is what would happen in \ real life) LDA yPlaneHi \ If yPlaneHi is non-zero, i.e. yPlane >= 256, then jump BNE aero8 \ to aero8 to skip the following three instructions, as \ we are high enough off the ground to roll the plane LDA yPlaneLo \ If yPlaneLo < 20, jump to aero9 to skip the roll, as CMP #20 \ we are too close to the ground BCC aero9 .aero8 LDA forceFactor+4 \ If the force factor for yLiftDrag = 39 then we are CMP #39 \ already stalling, so jump to aero9 to make the BEQ aero9 \ stalling sound without applying any roll \ Otherwise we are not already stalling, but we are now, \ so we apply a roll to the plane to simulate one of the \ wings stalling before the other LDA yTurnTop \ Set the C flag to the sign bit of yTurn so we can pass ASL A \ it to the AddScaled routine, so the roll will be in \ direction of the current yaw (i.e. the wing dips as \ the plane slips in that direction) LDY #4 \ Set the scale factor in Y so we add or subtract \ (A 0) >> 5 LDX #2 \ Set X so the call to AddScaled updates the zTurn \ variable LDA xTurnTop \ Set A = xTurnTop with bits 0 to 5 flipped, so (A 0) is EOR #%00111111 \ larger when the current pitch rate is smaller, and \ vice versa JSR AddScaled \ Set zTurn = zTurn +/- (A 0) >> 5 \ \ which applies a roll in the direction of the current \ yaw, with the amount of roll being inversely \ proportional to the current rate of pitch .aero9 LDA L \ Fetch the current value of onGround BNE aero10 \ If onGround is non-zero then we are on the ground, so \ skip the following, as we can't be stalling if we are \ on the ground LDA #4 \ Make sound #4, a short, low beep to indicate that the JSR MakeSound \ plane is stalling LDA #39 \ Set A = 39 so that the force factor for yLiftDrag is BNE aero11 \ set to 39 below (this BNE is effectively a JMP as A is \ never zero) .aero10 LDA #156 \ Set A = 156 so that the force factor for yLiftDrag is \ set to 156 below .aero11 STA forceFactor+4 \ Set the force factor for yLiftDrag to the value in A, \ which will be either 39 (if we are stalling) or 156 \ (in normal flight)