Skip to navigation

Flight model: ScaleFlightForces

Name: ScaleFlightForces [Show more] Type: Subroutine Category: Flight model Summary: Scale the flight forces by the relevant scale factors Deep dive: The flight model Ripping the wings off
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyFlightModel (Part 2 of 7) calls ScaleFlightForces

For each of the 11 flight forces, this routine calculates the following: scaledForce = unscaledForce * forceFactor * 2 ^ scaleFactor The 11 flight forces are: * (xMoments, yMoments, zMoments) * (xLiftDrag, yLiftDrag, zLiftDrag) * zSlipMoment * yFlapsLift * (xControls, yControls, zControls) The scaled results are stored in xMomentsSc, xLiftDragSc and so on. This routine also tests for high g-forces, which occur if: |yLiftDrag| >= 2048 / 39 = 53 if we are stalling 2048 / 156 = 13 if we are not stalling
.ScaleFlightForces LDX #12 \ We are about to work our way through the flight \ forces, so set a counter in X to act as an index into \ these three tables: \ \ * The unscaled forces from xMoments to zControls \ \ * The forceFactor table \ \ * The scaleFactor table \ \ * The scaled forces from xMomentsSc to zControlsSc \ \ These three tables have the same structure, so we can \ iterate through all of them using an index in X that \ goes from 12 to 0 while skipping over 8 and 9 .scal1 CPX #9 \ If X <> 9, jump to scal2 to skip the following BNE scal2 \ instruction LDX #7 \ If we get here then X = 9, so set X = 7 so we skip \ indexes 8 and 9 .scal2 LDA forceFactor,X \ Set R to the force factor for the X-th force STA R LDY xMomentsLo,X \ Set (A Y) to the X-th unscaled force LDA xMomentsHi,X JSR Multiply8x16-6 \ Store X in VV and set (G W V) = (A Y) * R \ \ Also set A to the high byte of the result in G, so we \ have: \ \ (A W V) = (A Y) * R \ \ so: \ \ (A W) = (A Y) * R / 256 LDX VV \ Retrieve X from VV so it once again contains the loop \ index CPX #4 \ If X <> 4, skip the following section BNE scal4 \ If we get here then X = 4, and the force factor for \ yLiftDrag determines whether the plane is stalling \ (156) or is in normal flight (39) TAY \ If the high byte of (A Y) * R is positive, then jump BPL scal3 \ to scal3 to skip the following instruction EOR #&FF \ Set A = ~A, so A now contains the high byte of the \ 24-bit result, flipped, so it contains: \ \ |A Y| * R / 256 .scal3 CMP #8 \ If A < 8, jump to scal4 to skip the next three BCC scal4 \ instructions \ If we get here then A >= 8, so: \ \ |A Y| * R / 256 >= 8 \ \ |A Y| * R >= 2048 \ \ |A Y| >= 2048 / 39 = 53 if we are stalling \ 2048 / 156 = 13 if we are not stalling \ \ where |A Y| = |yLiftDrag| LDA #3 \ Make sound #3, a long, medium beep that indicates high JSR MakeSound \ g-forces are ripping the wings off LDX #4 \ Set X = 4 once again, as it will have been corrupted \ by the call to MakeSound .scal4 LDY scaleFactor,X \ Set Y = the X-th entry in the scaleFactor table, which \ contains the number of places to shift the result, \ with a negative number meaning a right shift, a \ positive number meaning a left shift, and a value of \ zero having no effect \ \ In other words, we multiply the result in (G W V) by \ 2^scaleFactor, where scaleFactor is a signed integer BEQ scal7 \ If the entry is zero, jump to scal7 to write the \ result to the scaled force BPL scal6 \ If the entry is positive, jump to scal6 to shift the \ result to the left \ If we get here then the entry is negative, so we shift \ the result to the right LDA #0 \ Set R = 0 to use as the byte to feed into the top byte STA R \ when right-shifting (G W V) LDA G \ If the high byte in G is negative, decrement R to &FF BPL scal5 \ so it feeds in bits of the correct sign DEC R .scal5 LSR R \ Shift (G W V) right by one place, shifting in bits ROR G \ from R into G ROR W ROR V INY \ Increment the shift counter BNE scal5 \ Loop back until we have shifted right by -Y places BEQ scal7 \ Jump to scal7 to write the result to the scaled force .scal6 ASL V \ Shift (G W V) left by one place ROL W ROL G DEY \ Increment the shift counter BNE scal6 \ Loop back until we have shifted left by Y places .scal7 LDA G \ Set (xMomentsScTop xMomentsScHi xMomentsScLo) STA xMomentsScTop,X \ = (G W V) LDA W \ STA xMomentsScHi,X \ so we have: LDA V \ STA xMomentsScLo,X \ scaledForce = unscaledForce * forceFactor \ * 2 ^ scaleFactor DEX \ Decrement the loop counter to move to the next flight \ factor BPL scal1 \ Loop back until we have processed all 13 flight \ factors RTS \ Return from the subroutine