.ScaleTyreForces LDY #78 \ Set Y = 78 LDA xTyreForceNoseLo \ Set (A T) = xTyreForceNose - xTyreForceRear SEC \ SBC xTyreForceRearLo \ starting with the low bytes STA T LDA xTyreForceNoseHi \ And then the high bytes SBC xTyreForceRearHi JSR Multiply8x16Signed \ Set: \ \ (A T) = (A T) * abs(A) * Y / 256 \ = (xTyreForceNose - xTyreForceRear) * 78 / 256 \ = (xTyreForceNose - xTyreForceRear) * 0.3 STA spinYawDeltaHi \ Set spinYawDelta = (A T) LDA T \ = (xTyreForceNose - xTyreForceRear) * 0.3 STA spinYawDeltaLo \ We now perform the following shifts, making sure to \ keep the signs intact: \ \ xTyreForceNose = xTyreForceNose >> 2 \ \ xTyreForceRear = xTyreForceRear >> 2 \ \ zTyreForceNose = zTyreForceNose >> 2 \ \ zTyreForceRear = zTyreForceRear >> 2 LDY #1 \ Set Y = 1, to act as a shift counter in the outer loop \ below, so we right-shift Y + 1 times (i.e. twice) .forc1 LDX #3 \ Set X = 3, to act as a variable counter in the inner \ loop to work through zTyreForceRear, zTyreForceNose, \ xTyreForceRear and xTyreForceNose (let's call this \ variableX) .forc2 LDA xTyreForceNoseHi,X \ Set A to the high byte of variableX CLC \ Clear the C flag, to use if variableX is positive BPL forc3 \ If A is positive, jump to forc3 to keep the C flag \ clear SEC \ Otherwise set the C flag, to use if variableX is \ negative \ The C flag now contains the sign bit of A .forc3 ROR xTyreForceNoseHi,X \ Set variableX = variableX >> 1 ROR xTyreForceNoseLo,X \ \ Keeping the sign intact DEX \ Decrement the inner loop counter in X BPL forc2 \ Loop back to forc2 until we have shifted all four \ variables to the right by one place DEY \ Decrement the shift counter in Y BPL forc1 \ Loop back until we have right-shifted Y + 1 times LDX #2 \ Set X = 2, to act as a variable counter in the \ following loop, iterating through values 0 and 2, as \ X is decremented twice at the end of the loop \ \ The loop references xTyreForceRear,X and \ xTyreForceNose,X, so the loop iterates through: \ \ * zTyreForceRear and zTyreForceNose when X = 2 \ \ * xTyreForceRear and xTyreForceNose when X = 0 \ \ The comments below are for when X = 2 LDA #1 \ Set G = 1, to use as the index for storing the STA G \ following calculation .forc4 LDA xTyreForceRearLo,X \ Set (U T) = zTyreForceRear STA T LDA xTyreForceRearHi,X STA U JSR MultiplyBy1Point5 \ Set (A T) = (U T) * 1.5 \ = zTyreForceRear * 1.5 STA U \ Set (U T) = (A T) \ = zTyreForceRear * 1.5 LDA T \ Set (A T) = (U T) + zTyreForceNose CLC \ = zTyreForceRear * 1.5 + zTyreForceNose ADC xTyreForceNoseLo,X \ STA T \ starting with the low bytes LDY #205 \ Set Y = 205 LDA U \ And then the high bytes ADC xTyreForceNoseHi,X JSR Multiply8x16Signed \ Set (A T) = (A T) * abs(A) * Y / 256 \ = (zTyreForceRear * 1.5 + zTyreForceNose) \ * 205 / 256 \ = (zTyreForceRear * 1.5 + zTyreForceNose) * 0.8 ASL T \ Set (A T) = (A T) * 2 ROL A \ = (zTyreForceRear * 1.5 + zTyreForceNose) * 1.6 LDY G \ Set zPlayerAccel = (A T) STA xPlayerAccelHi,Y \ = (zTyreForceRear * 1.5 + zTyreForceNose) * 1.6 LDA T STA xPlayerAccelLo,Y DEC G \ Decrement G so the next iteration stores the result in \ xPlayerAccel DEX \ Decrement X twice so the next iteration calculates DEX \ (xTyreForceRear * 1.5 + xTyreForceNose) * 1.6 BPL forc4 \ Loop back until we have calculated both zPlayerAccel \ and xPlayerAccel LDA zPlayerAccelHi \ Set zTyreForceBoth = zPlayerAccelHi STA zTyreForceBoth RTS \ Return from the subroutineName: ScaleTyreForces [Show more] Type: Subroutine Category: Driving model Summary: Scale the tyre forces and calculate the combined tyre force on the player Deep dive: The core driving model Matching the code to the driving modelContext: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyDrivingModel calls ScaleTyreForces
Calculate the following: spinYawDelta = (xTyreForceNose - xTyreForceRear) * 0.3 xTyreForceNose = xTyreForceNose >> 2 xTyreForceRear = xTyreForceRear >> 2 zTyreForceNose = zTyreForceNose >> 2 zTyreForceRear = zTyreForceRear >> 2 xPlayerAccel = (xTyreForceRear * 1.5 + xTyreForceNose) * 1.6 zPlayerAccel = (zTyreForceRear * 1.5 + zTyreForceNose) * 1.6 zTyreForceBoth = zPlayerAccelHi
[X]
Subroutine Multiply8x16Signed (category: Maths (Arithmetic))
Multiply an 8-bit and a 16-bit number and apply a sign to the result
[X]
Subroutine MultiplyBy1Point5 (category: Maths (Arithmetic))
Multiply a 16-bit signed number by 1.5
[X]
Label forc1 is local to this routine
[X]
Label forc2 is local to this routine
[X]
Label forc3 is local to this routine
[X]
Label forc4 is local to this routine
[X]
Variable spinYawDeltaHi (category: Driving model)
High byte of the change in the spin yaw angle for the player's car
[X]
Variable spinYawDeltaLo (category: Driving model)
Low byte of the change in the spin yaw angle for the player's car
[X]
Variable xPlayerAccelHi (category: Driving model)
High byte of the x-coordinate of the change in velocity of the player's car in the player's frame of reference
[X]
Variable xPlayerAccelLo (category: Driving model)
Low byte of the x-coordinate of the change in velocity of the player's car in the player's frame of reference
[X]
Variable xTyreForceNoseHi (category: Driving model)
High byte of the x-coordinate of the force vector produced by the front tyres in the nose of the car
[X]
Variable xTyreForceNoseLo (category: Driving model)
Low byte of the x-coordinate of the force vector produced by the front tyres in the nose of the car
[X]
Variable xTyreForceRearHi (category: Driving model)
High byte of the x-coordinate of the force vector produced by the rear tyres of the car
[X]
Variable xTyreForceRearLo (category: Driving model)
Low byte of the x-coordinate of the force vector produced by the rear tyres of the car
[X]
Variable zPlayerAccelHi (category: Driving model)
High byte of the z-coordinate of the change in velocity of the player's car in the player's frame of reference
[X]
Variable zTyreForceBoth (category: Driving model)
High byte of the z-coordinate of the force vector produced by the front and tyres combined