Skip to navigation

Landscape: GetHighestTiles

Name: GetHighestTiles [Show more] Type: Subroutine Category: Landscape Summary: Calculate both the highest tiles in each 4x4 block of tiles in the landscape and the altitude of the highest tile in the landscape
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * AddEnemiesToTiles calls GetHighestTiles

Returns: maxAltitude The altitude (i.e. y-coordinate) of the highest tile in each 4x4 block in the landscape xTileMaxAltitude The tile x-coordinate of the highest tile in each 4x4 block in the landscape zTileMaxAltitude The tile z-coordinate of the highest tile in each 4x4 block in the landscape tileAltitude The altitude of the highest tile in the landscape
.GetHighestTiles \ This routine works through the tile corners in the \ landscape in 4x4 blocks and finds the highest flat \ tile within each block, so we can consider putting an \ enemy there \ \ To do this we split the 32x32-corner landscape up into \ 8x8 blocks of 4x4 tile corners each, iterating along \ each row of 4x4 blocks from left to right, and then \ moving back four rows to the next row of 4x4 blocks \ behind \ \ Because the tile corners along the right and back \ edges of the landscape don't have tile altitudes \ associated with them, we ignore those corners LDX #0 \ Set X to loop from 0 to 63, to use as a block counter \ while we work through the landscape in blocks of 4x4 \ tiles, of which there are 64 in total STX tileAltitude \ Set tileAltitude = 0 so we can use it to store the \ maximum tile altitude as we work through the landscape \ (so that's the altitude of the landscape's highest \ tile) .high1 TXA \ Set A = X mod 8 AND #7 \ \ The 32x32-tile landscape splits up into 8x8 blocks of \ 4x4 tiles each, so this sets A to the number of the \ block along the left-to-right x-axis row that we are \ working along (so A goes from 0 to 7 and around again) ASL A \ Set xBlock = A * 4 ASL A \ STA xBlock \ So xBlock is the tile x-coordinate of the tile in the \ front-left corner of the 4x4 block we are analysing \ (so xBlock goes 0, 4, 8 ... 24, 28) TXA \ Set A = X div 8 AND #%00111000 \ \ X is in the range 0 to 64, so this instruction has the \ same effect as AND #%11111000, which is equivalent to \ a div 8 operation \ \ The 32x32-tile landscape splits up into 8x8 blocks of \ 4x4 tiles each, so this sets A to the number of the \ row of 4x4 blocks along the front-to-back z-axis row \ that we are working along (so A goes 0, 8, 16 ... 56) LSR A \ Set zBlock = A / 2 STA zBlock \ \ So zBlock is the tile z-coordinate of the tile in the \ front-left corner of each of the 4x4 blocks in the row \ that we are analysing (so zBlock goes 0, 4, 8 ... 24, \ 28) \ Essentially, by this point we have converted the loop \ counter in X from the sequence 0 to 63 into an inner \ loop of xBlock and an outer loop of zBlock, with both \ variables counting 0, 4, 8 ... 24, 28 \ \ We can now use (xBlock, zBlock) as a tile coordinate \ and we can store the highest tile altitude within each \ 4x4 block using the index in X LDA #0 \ Zero the X-th entry in the maxAltitude table, which STA maxAltitude,X \ is where we will store the highest tile altitude \ within block X LDA #4 \ Set zCounter = 4 to iterate along the z-axis through STA zCounter \ each tile in the 4x4 block we are analysing, so \ zCounter iterates from 4 down to 1 LDA zBlock \ Set zTile = zBlock STA zTile \ \ So we can use zTile as the tile z-coordinate of the \ tile to analyse within the 4x4 block CMP #28 \ If zBlock < 28 then then we are not on the tile row at BCC high2 \ the back of the landscape, so jump to high2 to skip \ the following instruction DEC zCounter \ We are on the tile row at the back of the landscape, \ so set zCounter = 3 so it iterates from 3 down to 1 \ for this block, because the blocks along the back row \ are only three tiles deep (as the landscape is 31 \ tiles deep) .high2 LDA #4 \ Set xCounter = 4 to iterate along the x-axis through STA xCounter \ each tile in the 4x4 block we are analysing, so \ xCounter iterates from 4 down to 1 LDA xBlock \ Set xTile = xBlock STA xTile \ \ So we can use xTile as the tile x-coordinate of the \ tile to analyse within the 4x4 block CMP #28 \ If xBlock < 28 then we are not at the right end of the BCC high3 \ tile row, so jump to high3 to skip the following \ instruction DEC xCounter \ We are at the right end of the tile row, so set \ xCounter = 3 so it iterates from 3 down to 1 for this \ block, because the last block on the row is only three \ tiles across (as the landscape is 31 tiles across) .high3 JSR GetTileData \ Set A to the tile data for the tile anchored at \ (xTile, zTile) \ \ This also sets the tile page in tileDataPage and the \ tile number in Y, so tileDataPage+Y now points to the \ tile data entry in the tileData table AND #%00001111 \ Set A to the tile shape for the tile, which is in the \ bottom nibble of the tile data BNE high5 \ If the shape is non-zero then the tile is not flat, so \ jump to high5 to move on to the next tile in the LDA (tileDataPage),Y \ Set A to the tile data for the tile anchored at \ (xTile, zTile) AND #%11110000 \ Set A to the tile altitude, which is in the top nibble \ of the tile data CMP maxAltitude,X \ If the altitude of the tile we are analysing is lower BCC high5 \ than the altitude we have currently stored in the \ maxAltitude table for this 4x4 tile block, jump to \ high5 to move on to the next tile, as this one isn't \ the highest in either this block or the landscape STA maxAltitude,X \ If we get here then the tile we are analysing is the \ highest in the 4x4 block so far, so store the altitude \ in the maxAltitude table for this 4x4 tile block so \ the table ends up recording the highest tile altitude \ in each 4x4 block CMP tileAltitude \ Set tileAltitude = max(tileAltitude, A) BCC high4 \ STA tileAltitude \ So tileAltitude contains the altitude of the highest \ tile that we've analysed so far, which means that \ tileAltitude ends up being set to the highest value \ in the entire landscape, which is the altitude of the \ highest tile of all .high4 LDA xTile \ Store the x-coordinate of the highest tile corner in STA xTileMaxAltitude,X \ this block (so far) in the xTileMaxAltitude table \ entry for this 4x4 block LDA zTile \ Store the z-coordinate of the highest tile corner in STA zTileMaxAltitude,X \ this block (so far) in the zTileMaxAltitude table \ entry for this 4x4 block .high5 INC xTile \ Increment xTile to move on to the next tile to the \ right, for the inner loop DEC xCounter \ Decrement the x-axis counter within this 4x4 block BNE high3 \ Loop back until we have processed all the tiles in the \ 4x4 block, working from left to right INC zTile \ Increment zTile to move on to the next tile towards \ the back, for the outer loop DEC zCounter \ Decrement the z-axis counter within this 4x4 block BNE high2 \ Loop back until we have processed all the tile rows in \ the 4x4 block, working from front to back INX \ Increment the block counter in X CPX #64 \ Loop back until we have processed all 63 4x4 blocks BCC high1 RTS \ Return from the subroutine