Skip to navigation


Maths (Geometry): RotateVector

Name: RotateVector [Show more] Type: Subroutine Category: Maths (Geometry) Summary: Rotate a vector by a rotation matrix
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * RotateCoordToCar calls RotateVector

If bit 7 of X is clear, this routine calculates: [ variableA ] [ cosYawAngle 0 -sinYawAngle ] [ variableY ] [ - ] = [ 0 1 0 ] . [ - ] [ variableA+1 ] [ sinYawAngle 0 cosYawAngle ] [ variableY+1 ] by doing these individual calculations: variableA = variableY * cosYawAngle + variableY+1 * sinYawAngle variableA+1 = variableY+1 * cosYawAngle - variableY * sinYawAngle If bit 7 of X is set, this routine calculates: [ variableA ] [ cosYawAngle 0 sinYawAngle ] [ variableY ] [ - ] = [ 0 1 0 ] . [ - ] [ variableA+1 ] [ -sinYawAngle 0 cosYawAngle ] [ variableY+1 ] by doing these individual calculations: variableA = variableY * cosYawAngle - variableY+1 * sinYawAngle variableA+1 = variableY+1 * cosYawAngle + variableY * sinYawAngle For it to work, the routine must be called with bit 6 of X set.
Arguments: Y Offset of the 16-bit signed number to multiply: * 0 = xPlayerSpeed and zPlayerSpeed * 6 = xPlayerAccel and zPlayerAccel A Offset of the variable to store the result in: * 3 = xAcceleration and zAcceleration * 8 = xVelocity and zVelocity X Details of the operation to perform on the second and fourth multiplications: * Bit 6 needs to be set * Bit 7 defines the sign to apply to the result: * 0 = do not negate the result * 1 = negate the result
.RotateVector STY N \ Set N to the offset of the 16-bit signed number, and \ let's call this number variableY (as it is specified \ by parameter Y) STA K \ Set K to the offset of the variable to store the \ result in, and let's call this number variableA (as it \ is specified by parameter A) STX GG \ Store the details of the operation to perform in GG LDX #1 \ Set X = 1, so in the call to MultiplyCoords we use \ cosYawAngle as the 16-bit sign-magnitude value to \ multiply LDA #%00000000 \ Set A = %00000000, so in the call to MultiplyCoords we \ overwrite the result rather than adding, and do not \ negate the multiplication JSR MultiplyCoords \ Set variableA = variableY * variableX \ = variableY * cosYawAngle DEX \ Set X = 0, so in the call to MultiplyCoords we use \ sinYawAngle as the 16-bit sign-magnitude value to \ multiply INC N \ Point to the next variable after the 16-bit signed \ number we just used, so in the call to MultiplyCoords \ we use variableY+1 as the 16-bit signed number LDA GG \ Set A to the details of the operation to perform in \ GG, as specified by parameter X \ \ Bit 6 of parameter X is always set in calls to this \ routine, so we add the result to variableA JSR MultiplyCoords \ Set: \ \ variableA = variableA + variableY+1 * variableX \ = variableA + variableY+1 * sinYawAngle \ \ if bit 7 of parameter X is clear, or: \ \ variableA = variableA - variableY+1 * sinYawAngle \ \ if bit 7 of parameter X is set INX \ Set X = 1, so in the call to MultiplyCoords we use \ cosYawAngle as the 16-bit sign-magnitude value to \ multiply INC K \ Point to the next variable after the one we just \ stored the result in, so in the call to MultiplyCoords \ we use variableA+1 to store the result LDA #%00000000 \ Set A = %00000000, so in the call to MultiplyCoords we \ overwrite the result rather than adding, and do not \ negate the multiplication JSR MultiplyCoords \ Set variableA+1 = variableY+1 * variableX \ = variableY+1 * cosYawAngle DEX \ Set X = 0, so in the call to MultiplyCoords we use \ sinYawAngle as the 16-bit sign-magnitude value to \ multiply DEC N \ Point back to the original variable for the 16-bit \ signed number we just used, so in the call to \ MultiplyCoords we use variableY again as the 16-bit \ signed number LDA GG \ Set A to the details of the operation to perform in EOR #%10000000 \ GG with bit 7 flipped, which is as specified by \ parameter X, but with a flipped sign \ \ Bit 6 of parameter X is always set in calls to this \ routine, so we add the result to variableA+1 JSR MultiplyCoords \ Set: \ \ variableA+1 = variableA+1 - variableY * variableX \ = variableA+1 - variableY * sinYawAngle \ \ if bit 7 of parameter X is clear, or: \ \ variableA+1 = variableA+1 + variableY * sinYawAngle \ \ if bit 7 of parameter X is set RTS \ Return from the subroutine