Skip to navigation

Landscape: GetTilesAtAltitude

Name: GetTilesAtAltitude [Show more] Type: Subroutine Category: Landscape Summary: Return a list of tile blocks at a specified altitude
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * AddEnemiesToTiles calls GetTilesAtAltitude

Argument: tileAltitude The altitude to search for
Returns: C flag Status flag: * Clear if at least one tile block is at an altitude of tileAltitude * Set if no tile blocks are at an altitude of tileAltitude, in which case X is set to &FF tilesAtAltitude A list of tile block numbers whose highest tiles match the altitude in tileAltitude T The number of entries in the list at tilesAtAltitude bitMask A bit mask with a matching number of leading zeroes as T
.GetTilesAtAltitude \ We start by fetching all the 4x4 tile blocks from the \ landscape whose altitude matches tileAltitude (so \ that's all the 4x4 blocks whose highest tile is at an \ altitude of tileAltitude) LDX #63 \ Set an index in X to work through all 4x4 tile blocks, \ of which there are 64 LDY #0 \ Set Y = 0 to count the number of tile blocks whose \ altitude matches tileAltitude .galt1 LDA maxAltitude,X \ If the highest tile in the X-th tile block does not CMP tileAltitude \ have an altitude of tileAltitude, jump to galt2 to BNE galt2 \ move on to the next tile block TXA \ Store the number of the tile block in the Y-th byte of STA tilesAtAltitude,Y \ tilesAtAltitude, so we end up compiling a list of all \ the tile blocks that have an altitude of tileAltitude INY \ Increment the counter in Y as we have just added a \ block number to tilesAtAltitude .galt2 DEX \ Decrement the block counter in X BPL galt1 \ Loop back until we have checked the altitudes of all \ the tile blocks \ By this point we have all the tile blocks with an \ altitude of tileAltitude in a list of length Y at \ tilesAtAltitude TYA \ Set A to the length of the list at tilesAtAltitude BEQ galt4 \ If the list is empty then jump to galt4 return from \ the subroutine with the C flag clear STA T \ Set T to the length of the list at tilesAtAltitude \ We now set bitMask to a bit mask that covers all the \ non-zero bits in the list length in A, so if A is of \ the form %001xxxxx, for example, then bitMask will \ contain %00111111, while A being like %000001xx will \ give a bitMask of %00000111 \ \ To do this we count the number of continuous clear \ bits at the top of A, and then use this as an index \ into the leadingBitMask table \ \ So we count zeroes from bit 7 down until we hit a 1, \ and put the result into Y LDY #&FF \ Set Y = -1 so the following loop counts the number of \ zeroes correctly .galt3 ASL A \ Shift A to the left, moving the top bit into the C \ flag INY \ Increment the zero counter in Y BCC galt3 \ Loop back to keep shifting and counting zeroes until \ we shift a 1 out of bit 7, at which point Y contains \ the length of the run of zeroes in bits 7 to 0 of the \ length of the list at tilesAtAltitude LDA leadingBitMask,Y \ Set bitMask to the Y-th entry from the leadingBitMask STA bitMask \ table, which will give us a bit mask with a matching \ number of leading zeroes as A CLC \ Clear the C flag to indicate that we have successfully \ found at least one tile block that matches the \ altitude in tileAltitude RTS \ Return from the subroutine .galt4 SEC \ If we get here then we have checked all 64 tile blocks \ and none of them are at an altitude of tileAltitude, \ so set the C flag to indicate that the returned list \ is empty RTS \ Return from the subroutine