Skip to navigation

Lander on the Acorn Archimedes

3D objects: PlaceObjectsOnMap

Name: PlaceObjectsOnMap [Show more] Type: Subroutine Category: 3D objects Summary: Randomly place a number of objects on the map, avoiding the sea and the launchpad Deep dive: Placing objects on the map
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file

The object map at objectMap contains one byte for each tile on the landscape. This byte determines which object (if any) appears on that tile, where objects are trees, buildings, rockets and so on.
.PlaceObjectsOnMap \ We start by initialising the object map \ at objectMap with values of &FF, which \ indicates no objects on the map MVN R0, #0 \ Set R0 to R3 to &FF so we can poke them MVN R1, #0 \ into memory at objectMap (this sets each MVN R2, #0 \ 32-bit register to &FFFFFFFF, which is the MVN R3, #0 \ same as four bytes, each of which is &FF) MOV R4, #256*256 \ Set R4 to use as a byte counter in the \ following loop, which works through each \ of the coordinates in the 256x256 map ADD R6, R11, #objectMap \ Set R6 to the address of the object map .snew1 STMIA R6!, {R0-R3} \ Store four words, or 16 bytes, at R6, \ updating R6 as we go, with each byte \ containing &FF SUBS R4, R4, #16 \ Subtract 16 from the byte counter in R4 \ as we just initialised 16 bytes BNE snew1 \ Loop back until we have set all bytes in \ the object map to &FF \ We now add 2048 randomly chosen 3D objects \ to the object map, each one at a random \ coordinate and of a random type ADD R6, R11, #objectMap \ Set R6 to the address of the object map MOV R5, #2048 \ Set R5 to a loop counter as we work \ through all 2048 objects .snew2 BL GetRandomNumbers \ Set R0 and R1 to random numbers MOV R8, R0 \ Set R8 = R0, so R8 is a random number \ \ We use the top byte of R8 below as the \ x-coordinate of the 3D object MOV R9, R0, LSL #8 \ Set R9 = R0 << 8 \ \ We use the top byte of R9 below as the \ z-coordinate of the 3D object, so the \ shift ensures that the top bytes of R8 \ and R9 are different STMFD R13!, {R0} \ Store R0 on the stack so it doesn't get \ corrupted by the following call to \ GetLandscapeAltitude BL GetLandscapeAltitude \ Set R0 to the altitude of the landscape at \ coordinates (x, z) = (R8, R9) MOV R14, R0 \ Set R14 to the landscape altitude returned \ in R0 LDMFD R13!, {R0} \ Retrieve the value of R0 from the stack \ that we stored above CMP R14, #SEA_LEVEL \ If R14 = LAUNCHPAD_ALTITUDE or SEA_LEVEL, CMPNE R14, #LAUNCHPAD_ALTITUDE \ jump to snew3 to skip the following, so we BEQ snew3 \ do not place any objects on the sea or the \ launchpad AND R0, R0, #7 \ Reduce R0 to the range 1 to 8, so this is ADD R0, R0, #1 \ a random number that we use to determine \ the type of object we're adding (so there \ are lots of trees): \ \ * 1 = small leafy tree \ * 2 = tall leafy tree \ * 3 = small leafy tree \ * 4 = small leafy tree \ * 5 = gazebo \ * 6 = tall leafy tree \ * 7 = fir tree \ * 8 = building \ \ See the objectTypes table for details of \ object types AND R9, R9, #&FF000000 \ Set the bottom three bytes of R9 to zero, \ leaving just the top byte, so we can use \ it in the following \ The object at coordinate (x, z) is stored \ at offset &zzxx within objectMap, where \ &xx and &zz are the top bytes of the full \ 32-bit coordinates \ \ In the following we set this address in \ R14: \ \ objectMap + (R8 >> 24) + (R9 >> 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 ADD R14, R6, R8, LSR #24 \ Set R14 = R6 + (R8 >> 24) + (R9 >> 16) ADD R14, R14, R9, LSR #16 STRB R0, [R14] \ Store R0 in the address in R14 to add the \ object to the map at the coordinates given \ by the top bytes of R8 and R9, at (R8, R9) .snew3 SUBS R5, R5, #1 \ Decrement the loop counter BPL snew2 \ Loop back until we have done all &800 \ iterations \ We now place three rockets along the right \ edge of the launchpad, with a rocket on \ every other tile, working from front to \ back, into the screen and parallel to the \ z-axis, and with each one having an \ x-coordinate of 7 MOV R0, #LAUNCHPAD_OBJECT \ Set R0 to the type of object along the \ right edge of the launchpad, which is a \ rocket of type 9 STRB R0, [R6, #&0107] \ Add the front rocket to coordinate (7, 1) STRB R0, [R6, #&0307] \ Add the middle rocket to coordinate (7, 3) STRB R0, [R6, #&0507] \ Add the rear rocket to coordinate (7, 5)