Skip to navigation

Aviator on the BBC Micro

Flight model: AdjustRotation

Name: AdjustRotation [Show more] Type: Subroutine Category: Flight model Summary: Move the plane and adjust its rotation
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyFlightModel (Part 6 of 7) calls AdjustRotation

This routine calculates the following: [ xPlane ] [ xPlane ] [ xVelocity ] [ yPlane ] = [ yPlane ] + [ yVelocity ] [ zPlane ] [ zPlane ] [ zVelocity ] to move the plane, and the following: [ xRotation ] [ xRotation ] [ dxRotation ] [ yRotation ] = [ yRotation ] + [ dyRotation ] [ zRotation ] [ zRotation ] [ dzRotation ] to rotate the plane. The plane is flipped around if this makes it point backwards.
.AdjustRotation LDX #2 \ Set a counter in X to work through the three axes (the \ comments below cover the iteration for the x-axis) .arot1 \ We now do the following calculation: \ \ xPlane = xPlane + xVelocity \ \ Looking at this in more detail, we take the 24-bit \ xPlane coordinate and append an extra bottom byte in \ xPlaneBot, like this: \ \ (xPlaneTop xPlaneHi xPlaneLo xPlaneBot) \ \ and then we add the 16-bit velocity, like this: \ \ (xVelocityTop xVelocityHi) \ \ The xPlaneBot byte is not used anywhere else, it's \ just used to keep track of the fractional part of this \ calculation \ \ so in terms of the original xPlane coordinate, we are \ effectively adding xVelocityTop, but keeping track of \ the fractional tally in xPlaneBot \ \ Fiknally, to support negative velocities, we extend \ xVelocity with new high and top bytes, set to 0 or &FF \ depending on the sign of xVelocity, so that's: \ \ (0 0 xVelocityTop xVelocityHi) \ \ for positive velocities, or: \ \ (&FF &FF xVelocityTop xVelocityHi) \ \ for negative velocities LDA #0 \ Set R = 0 to act as the high and top bytes in the STA R \ following addition LDA xPlaneBot,X \ Set xPlaneBot = xPlaneBot + xVelocityHi CLC \ ADC xVelocityHi,X \ so we've added the fractional parts and set the C flag STA xPlaneBot,X \ accordingly LDA xVelocityTop,X \ Set A = xVelocityTop, ready to add the xPlaneLo and \ xVelocityTop bytes BPL arot2 \ If A is negative, decrement R to &FF so we can use it DEC R \ as the high and top bytes for the velocity .arot2 ADC xPlaneLo,X \ Set xPlaneLo = xPlaneLo + xVelocityTop STA xPlaneLo,X \ \ so now we've added the low bytes LDA xPlaneHi,X \ And then we do the high bytes ADC R STA xPlaneHi,X LDA xPlaneTop,X \ And then the top bytes ADC R \ STA xPlaneTop,X \ so we now have the result we want: \ \ (xPlaneTop xPlaneHi xPlaneLo xPlaneBot) += \ (xVelocityTop xVelocityHi) LDA xRotationLo,X \ Set xRotation = xRotation + dxRotation CLC \ ADC dxRotationLo,X \ starting with the low bytes STA xRotationLo,X LDA xRotationHi,X \ And then the high bytes ADC dxRotationHi,X STA xRotationHi,X DEX \ Decrement the loop counter to move to the next axis BPL arot1 \ Loop back until we have processed all three axes ASL A \ At the end of the above loop, A = xRotationHi, so this EOR xRotationHi \ checks whether bit 6 and 7 of xRotationHi are the same BPL arot4 \ and if they are, it jumps to arot4 to return from the \ subroutine \ \ Bits 6 and 7 of xRotationHi are the same when the \ rotation angle is either 0 to 63 or 192 to 255 - in \ other words, when the plane is facing forwards: \ \ * 0 = straight ahead (bit 6 clear, bit 7 clear) \ * 64 = vertical up (bit 6 set, bit 7 clear) \ * 128 = backwards (bit 6 clear, bit 7 set) \ * 192 = nosedive (bit 6 set, bit 7 set) \ \ so this only runs the following if the plane is now \ pointing backwards, in which case we set bit 7 of the \ rotation in the y- and z-axes (which adds 128, or \ rotates by 180 degrees), and reflect the x-axis by \ subtracting the rotation from 128 LDX #1 \ Set a counter in X to work through the y- and z-axes .arot3 LDA yRotationHi,X \ Flip the sign of yRotationHi and zRotationHi EOR #%10000000 STA yRotationHi,X DEX \ Decrement the loop counter to move to the next axis BPL arot3 \ Loop back until we have processed both axes LDA #0 \ Set xRotation = (128 0) - xRotation, starting with the SEC \ low bytes SBC xRotationLo STA xRotationLo LDA #128 \ And then the high bytes SBC xRotationHi STA xRotationHi .arot4 RTS \ Return from the subroutine