Skip to navigation

Lander on the Acorn Archimedes

Player: MoveAndDrawPlayer (Part 3 of 5)

Name: MoveAndDrawPlayer (Part 3 of 5) [Show more] Type: Subroutine Category: Player Summary: Check for collisions and draw the ship Deep dive: Drawing 3D objects Collisions and bullets Flying by mouse
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
CMP R1, #0 \ If R1 (i.e. the y-coordinate of the ship) MOVPL R1, #0 \ is positive, then set it to zero \ \ As we store this value as the camera's \ y-coordinate below, this ensures that the \ camera doesn't drop down all the way with \ the ship in last few moments before it \ lands, and similarly it doesn't start \ rising up with the ship as it takes off \ until the ship is at a reasonable height ADD R2, R2, #CAMERA_PLAYER_Z \ Set R2 to the z-coordinate we want to use \ for the camera, which is at the back of \ the landscape ADD R14, R11, #xCamera \ Set (xCamera, yCamera, zCamera) to the STMIA R14, {R0-R2} \ coordinates in (R0, R1, R2), which is at \ the back of the landscape and in the \ middle \ \ This sets the camera so that it follows \ the player's ship as it flies around, \ and is positioned at the back of the \ visible screen MOV R8, R0 \ Set (R8, R9) to the point on the landscape MOV R9, R2 \ that's directly below the player, by SUB R9, R9, #CAMERA_PLAYER_Z \ setting (R8, R9) to the ship's (x, z) \ coordinates in (R0, R2) and subtracting \ the five tiles we added above BL GetLandscapeAltitude \ Set R0 to the altitude of the landscape at \ coordinates (x, z) = (R8, R9) SUB R0, R0, #UNDERCARRIAGE_Y \ Set R0 to the altitude of a point that's \ the height of the ship's undercarriage \ above the point on the landscape beneath \ the player, which is the lowest altitude \ the player can be without being in danger \ of hitting the ground with the bottom of \ the ship LDR R1, [R11, #yPlayer] \ Set R14 to the y-coordinate of the player \ in yPlayer SUB R14, R0, R1 \ If R0 - yPlayer >= SAFE_HEIGHT (1.5 tile CMP R14, #SAFE_HEIGHT \ sizes) then this means the bottom of the BHS ship6 \ player's ship is safely clear of objects \ on the ground, as SAFE_HEIGHT is the \ minimum safe height for avoiding objects \ on the ground, and the undercarriage of \ the player's ship is above this height \ \ So if this is the case, jump to ship6 to \ skip the following set of collision \ checks, as we know we are safe STMFD R13!, {R0} \ Store R0 on the stack so we can retrieve \ it below ADD R14, R11, #objectMap \ Set R14 to the address of the object map AND R9, R9, #&FF000000 \ Clip R9 down to the nearest tile ADD R14, R14, R8, LSR #24 \ Set R14 = R6 + (R8 >> 24) + (R9 >> 16) ADD R14, R14, R9, LSR #16 \ \ R8 is shifted into the bottom byte of R14, \ so that's the x-coordinate, and R9 is \ shifted into the second byte of R14, so \ that's the z-coordinate, so R14 points to \ the object map entry for coordinate \ (R8, R9) LDRB R0, [R14] \ Set R0 to the byte in the object map at \ the coordinate (R8, R9) CMP R0, #0 \ If the object map entry is zero, jump to BEQ ship5 \ ship5 to skip the following (though this \ shouldn't ever happen, as an object type \ of zero is never added to the object map) CMP R0, #12 \ If R0 < 12 then the object map entry is a ADDLO R13, R13, #4 \ valid object number in the range 1 to 11, BLO LoseLife \ so the player's ship just hit the object \ below it on the ground, so jump to \ LoseLife to show the explosion animation \ and lose a life .ship5 LDMFD R13!, {R0} \ Retrieve R0 from the stack, so it is once \ again the lowest altitude the player can \ be without being in danger of hitting the \ ground .ship6 \ If we get here then R0 is the lowest \ altitude the player can be without being \ in danger of hitting the ground, and R1 is \ the y-coordinate of the player, i.e. the \ player's altitude CMP R1, R0 \ If R1 > R0 then the player is lower down BLGT LandOnLaunchpad \ then the safe altitude, so call \ LandOnLaunchpad to check whether we have \ landed on the launchpad (as we need to be \ within the danger zone in order to land) CMP R1, #0 \ If R1 (i.e. the y-coordinate of the ship) MOVMI R1, #0 \ is negative, then set it to zero \ \ This is the converse of the test we did at \ the start of this part, as it sets R1 to \ zero only when the altitude of the player \ is higher than zero, so this only keeps \ R1 set to the player's y-coordinate when \ they are really close to the ground \ \ As we pass this value to DrawObject below, \ this means we draw the player's ship in \ the middle of the screen most of the time \ (by passing an R1 of zero to DrawObject), \ but when the ship is close to the ground, \ we draw the ship lower down the screen ADD R3, R11, #rotationMatrix \ Set R3 to the address of the ship's \ rotation matrix to pass to DrawObject LDR R14, objectPlayerAddr \ Set objectData to the object blueprint STR R14, [R11, #objectData] \ for the player's ship MOV R0, #0 \ Set the coordinates in (R0, R1, R2) so MOV R2, #LANDSCAPE_Z_MID \ the ship gets drawn in the middle of the \ screen or slightly below if the ship is \ near the ground (as R0 = 0 and R1 is set \ as described above), at a position into \ the screen of LANDSCAPE_Z_MID, which \ places it above the middle of the \ landscape \ \ This works because the landscape offset \ pushes the far edge of the landscape 20 \ tiles into the screen, and the landscape \ is ten tiles deep, so the centre is 15 \ tiles into the screen BL DrawObject \ Draw the player's ship with the correct \ orientation and position LDRB R10, [R11, #crashedFlag] \ DrawObject sets crashedFlag to -1 if the CMP R10, #0 \ ship is lower down than its shadow, to BLNE LoseLife \ indicate that it has crashed, so jump to \ LoseLife is this is the case