.MoveAndDrawPlayer STMFD R13!, {R14} \ Store the return address on the stack \ We start by reading the position of the \ mouse and generating a rotation matrix for \ the player's ship, based on its new \ orientation SWI OS_Mouse \ Read the mouse coordinates, returning: \ \ R0 = x-coordinate \ \ R1 = y-coordinate \ \ R2 = mouse buttons (%lmr) STRB R2, [R11, #fuelBurnRate] \ Set the fuel burn rate to the mouse button \ result, so it's set to: \ \ * %000 (0) if no buttons are being \ pressed \ \ * %001 (1) if the right button is being \ pressed (i.e. fire bullets) \ \ * %010 (2) if the middle button is being \ pressed (i.e. hover) \ \ * %100 (4) if the left button is being \ pressed (i.e. full thrust) \ \ Bit 0 of the fuel rate is ignored in the \ fuel calculations, so firing bullets does \ not burn fuel, even though fuelBurnRate is \ set to a non-zero value LDR R14, [R11, #fuelLevel] \ If the fuel level is zero, also zero the CMP R14, #0 \ fuel burn rate, as we can't burn fuel that STREQB R14, [R11, #fuelBurnRate] \ we don't have \ At the start of each new life, the mouse \ is initialised to coordinates (511, 511) CMP R0, #1024 \ Cap the mouse x-coordinate in R0 so it's MOVHS R0, #1024 \ in the range 0 to 1023 SUBHS R0, R0, #1 SUB R0, R0, #512 \ Convert R0 into the range -512 to +511 RSB R1, R1, #1024 \ Set R1 = 1024 - R1 - 512 SUB R1, R1, #512 \ = 512 - R1 \ \ So the mouse y-coordinate in R1 is now in \ the range -512 to +512 MOV R0, R0, LSL #22 \ Scale both mouse coordinates up as far as MOV R1, R1, LSL #22 \ possible without losing data (512 << 22 is \ &80000000, so this is as high as we can \ go) BL GetMouseInPolarCoordinates \ Convert the mouse coordinates into polar \ coordinates, returning the polar angle in \ R1 and the polar distance in R0 CMP R0, #&40000000 \ Cap the polar distance in R0 so it's in MOVHS R0, #&40000000 \ the range 0 to &3FFFFFFF SUBHS R0, R0, #1 MOV R0, R0, LSL #1 \ Scale R0 to the range 0 to &7FFFFFFE LDR R2, [R11, #shipPitch] \ Set R2 = shipPitch LDR R3, [R11, #shipDirection] \ Set R3 = shipDirection SUBS R4, R3, R1 \ Set R4 = R3 - R1 \ = shipDirection - polar angle BMI ship1 \ If the result is negative, jump to ship1 \ so we cap R4 against negative values CMP R4, #&30000000 \ Cap the value in R4 to a maximum magnitude MOVHS R4, #&30000000 \ of &30000001 B ship2 \ Jump to ship2 to skip the following and \ keep going .ship1 CMN R4, #&30000000 \ Cap the value in R4 to a maximum magnitude MVNLO R4, #&30000000 \ of -&30000001 .ship2 SUBS R5, R2, R0 \ Set R5 = R2 - R0 \ = shipPitch - polar distance BLE ship3 \ If the result is zero or negative, jump to \ ship3 so we cap R5 against negative values CMP R5, #&30000000 \ Cap the value in R5 to a maximum magnitude MOVHS R5, #&30000000 \ of &30000001 B ship4 \ Jump to ship4 to skip the following and \ keep going .ship3 CMN R5, #&30000000 \ Cap the value in R5 to a maximum magnitude MVNLO R5, #&30000000 \ of -&30000001 .ship4 \ We now update the rotation angles with the \ latest mouse values (in the form of the \ distance and angle) \ \ We do this by adding half of the new value \ and half of the old value, which seems to \ apply some kind of damping to the controls SUB R0, R2, R5, ASR #1 \ Set R0 = R2 - R5 / 2 \ = shipPitch \ - (shipPitch - distance) / 2 SUB R1, R3, R4, ASR #1 \ Set R1 = R3 - R4 / 2 \ = shipDirection \ - (shipDirection - angle) / 2 STR R0, [R11, #shipPitch] \ Store the updated value in shipPitch STR R1, [R11, #shipDirection] \ Store the updated value in shipDirection BL CalculateRotationMatrix \ Calculate the rotation matrix from the \ updated angles given in R0 and R1, so \ this sets the rotation matrix for the \ player's ship \ Now that we have the player's rotation \ matrix, we can move on to the ship's \ movement in spaceName: MoveAndDrawPlayer (Part 1 of 5) [Show more] Type: Subroutine Category: Player Summary: Process player movement and draw the player's ship into the graphics buffers, starting with reading the mouse position Deep dive: Flying by mouseContext: See this subroutine in context in the source code References: This subroutine is called as follows: * MainLoop calls MoveAndDrawPlayer
[X]
Subroutine CalculateRotationMatrix (category: Maths (Geometry))
Calculate the rotation matrix
[X]
Subroutine GetMouseInPolarCoordinates (Part 1 of 2) (category: Maths (Geometry))
Convert the mouse x- and y-coordinates into polar coordinates, starting by calculating the polar angle
[X]
Configuration variable OS_Mouse = &1C
The operating system call to read the mouse status
[X]
Configuration variable fuelBurnRate = &15C
The current fuel burn rate (bit 0 is ignored)
[X]
Configuration variable fuelLevel = &128
The player's fuel level
[X]
Label ship1 is local to this routine
[X]
Label ship2 is local to this routine
[X]
Label ship3 is local to this routine
[X]
Label ship4 is local to this routine
[X]
Configuration variable shipDirection = &154
The direction in which the player's ship faces, which is angle b in the rotation matrix, and which is determined by the angle of the mouse from the centre point
[X]
Configuration variable shipPitch = &158
The pitch of the player's ship, which is angle a in the rotation matrix, and which is determined by the distance of the mouse from the centre point