Skip to navigation


Maths (Arithmetic): MultiplyCoords

Name: MultiplyCoords [Show more] Type: Subroutine Category: Maths (Arithmetic) Summary: Multiply a 16-bit coordinate value and a 16-bit factor, optionally tallying or changing the sign of the result
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * RotateVector calls MultiplyCoords * ApplySteeringForce calls via MultiplyCoords+7 * ApplySteeringSpeed calls via MultiplyCoords+7

This routine multiplies two 16-bit values and stores the result, optionally negating the result, or adding it to the existing contents of the destination. The first number (specified by parameter N, so let's call it variableN) is a 16-bit signed integer, while the second number (specified by parameter X, so let's call it variableX) is a 16-bit sign-magnitude number with the sign in bit 0 of the low byte. The result is stored in the variable specified by parameter K, so let's call it variableK. The values of bits 6 and 7 of A affect the result as follows: * If A = %00000000, then we calculate the following: variableK = variableN * variableX * If A = %01000000, then we calculate the following: variableK = variableK + variableN * variableX * If A = %10000000, then we calculate the following: variableK = - variableN * variableX * If A = %11000000, then we calculate the following: variableK = variableK - variableN * variableX
Arguments: N Offset of the 16-bit signed number to multiply: * 0 = xPlayerSpeed * 1 = zPlayerSpeed * 6 = xPlayerAccel * 7 = zPlayerAccel * 8 = xVelocity * 9 = zVelocity * 10 = xTyreForceNose * 12 = zTyreForceNose X Offset of the 16-bit sign-magnitude value to multiply: * 0 = sinYawAngle * 1 = cosYawAngle * 2 = (steeringHi steeringLo) K Offset of the variable to store the result in: * 3 = xAcceleration * 4 = zAcceleration * 8 = xVelocity * 9 = zVelocity * 12 = zTyreForceNose * 14 = xSteeringForce A Details of the operation to perform: * Bit 6 defines whether we add or store: * 0 = store the result in the variable defined by K, overwriting the existing contents * 1 = add the result to the variable defined by K * Bit 7 defines the sign to apply to the result: * 0 = do not negate the multiplication * 1 = negate the multiplication
Other entry points: MultiplyCoords+7 Use the following variables instead of the above: * Y = Offset of the 16-bit signed number to multiply (instead of N) * A = Offset of the variable to store the result in (instead of K) * H = Details of the operation to perform (instead of A)
.MultiplyCoords LDY N \ Set Y to the offset of the 16-bit signed number STA H \ Store the details of the operation to perform in H JMP mcoo1 \ Jump to mcoo1 to skip the MultiplyCoords+7 entry \ point \ This is where we join the subroutine when called via \ MultiplyCoords+7 STA K \ Set K to the offset of the variable to store the \ result in .mcoo1 LDA xPlayerSpeedHi,Y \ Set (QQ PP) to the 16-bit signed number pointed to by STA PP \ Y (variableY) LDA xPlayerSpeedTop,Y STA QQ LDA sinYawAngleLo,X \ Set (SS RR) to the 16-bit sign-magnitude number STA RR \ pointed to by X (variableX) LDA sinYawAngleHi,X STA SS JSR Multiply16x16 \ Set (A T) = (QQ PP) * (SS RR) \ \ And apply the sign from bit 7 of H STA U \ Set (U T) = (A T) \ = (QQ PP) * (SS RR) LDY K \ Set Y to K, so we can store the result in the variable \ pointed to by K BIT H \ If bit 6 of H is set, then jump to AddCoords to add BVS AddCoords \ the result to the variable pointed to by K LDA T \ Store the result in the variable pointed to by K STA xPlayerSpeedHi,Y LDA U STA xPlayerSpeedTop,Y RTS \ Return from the subroutine