Aviator on the BBC Micro

# Flight model: ApplyFlightModel (Part 1 of 7)

```       Name: ApplyFlightModel (Part 1 of 7)                          [Show more]
Type: Subroutine
Category: Flight model
Summary: Apply the flight model to the plane, starting by calculating the
effect of gravity and the undercarriage springs
Deep dive: The flight model
On-ground calculations
Context: See this subroutine in context in the source code
References: This subroutine is called as follows:
* UpdateFlightModel (Part 4 of 4) calls ApplyFlightModel

This part does the following:

* Set gravity to the following vector, rotated to the plane's frame of
reference using matrix 4:

[ xGravity ]             [   0  ]
[ yGravity ] = matrix4 x [ -512 ]
[ zGravity ]             [   0  ]

* If we are on the ground with the undercarriage down, and we are
accelerating downwards, we push back up to simulate the springs in the
undercarriage by setting the gravity vector to the following, again
rotating it to the plane's frame of reference using matrix 4:

[ xGravity ]             [              0              ]
[ yGravity ] = matrix4 x [ -512 - (dyVelocity / 2 + 1) ]
[ zGravity ]             [              0              ]

.ApplyFlightModel

LDX #253               \ Set the gravity vector (which is stored in point 253)
JSR SetPointToOrigin   \ to (0, 0, 0), so:
\
\   (xGravity, yGravity, zGravity) = (0, 0, 0)

\ When we are flying normally, the gravity vector is:
\
\   (0, &FE00, 0) = (0, -512, 0)
\
\ so, as you would expect, gravity pulls the plane down
\ along the y-axis (which is the up-down axis)

LDA #&FE               \ Set A = &FE to set as yGravityHi for when we are
\ flying normally

LDX onGround           \ Set L to the value of onGround, so we can check it
STX L                  \ again in part 5

BEQ fmod1              \ If onGround is zero then we are not on the ground,
\ so jump to fmod1 to skip the following and set the
\ gravity vector to (0, -512, 0)

LDX ucStatus           \ If ucStatus is zero then the undercarriage is up, so
BEQ fmod1              \ jump to fmod1 to skip the following and set the
\ gravity vector to (0, -512, 0)

LDX dyVelocityHi       \ If dyVelocity is positive then the rate of change of
BPL fmod1              \ velocity in the vertical axis is positive - i.e. the
\ skip the following and set the gravity vector to
\ (0, -512, 0)

\ If we get here then we are on the ground, the
\ undercarriage is down, and dyVelocity is negative, so
\ the plane is accelerating down and we need to change
\ the gravity vector so it pushes upwards, to simulate
\ the springs in the undercarriage

STX Q                  \ Set (Q A) = (dyVelocityHi dyVelocityLo)
LDA dyVelocityLo       \           = dyVelocity

SEC                    \ Set (Q A) = (Q A) / 2
ROR Q                  \           = dyVelocity / 2
ROR A                  \
\ making sure to retain the correct sign in bit 7 of Q
\ (as dyVelocity is negative)

EOR #&FF               \ Set yGravityLo = ~A
STA yGravityLo         \                = 255 - A

LDA #254               \ Set yGravityHi = 254 - Q - 1
CLC                    \                = 253 - Q
SBC Q                  \

\ So the above does this:
\
\   yGravity = (253 255) - (Q A)
\            = -513 - (Q A)
\            = -512 - (dyVelocity / 2 + 1)
\
\ where dyVelocity is negative, so this reduces the
\ gravitational pull by half of the plane's acceleration
\ down - in other words, the wheels push up by half the
\ acceleration downwards, bouncing the plane up like a
\ spring

.fmod1

STA yGravityHi         \ Set yGravityHi = A, to set the y-axis of the gravity
\ vector as required

\ Finally, we calculate the gravity vector's coordinates
\ in the world, so we get the gravity vector rotated by
\ the plane's orientation, i.e. relative to the plane
\ rather than the world
\
\ We can get away with only rotating in the pitch and
\ roll axes as the gravity vector only has an non-zero
\ value in the y-axis, so the yaw rotation wouldn't
\ affect the result anyway

LDA #253               \ Set GG to ID of the gravity vector (which is stored in
STA GG                 \ point 253), to pass to the call to SetPointCoords

LDA #27                \ Set the matrix number so the call to SetPointCoords
STA matrixNumber       \ uses matrix 4 in the calculation, so it rotates the
\ point by the roll and pitch angles, but not the yaw,
\ as rotating a vertical vector by a yaw angle has no
\ effect

JSR SetPointCoords     \ Calculate the coordinates for the gravity vector,
\ using matrix 4, which only performs the pitch and roll
\ rotations

\ So (xGravity, yGravity, zGravity) now contains the
\ gravity vector, rotated to the plane's point of view
```