.GetTileAltitudes LDA #0 \ Set the low byte of (Q P) = &7F00 STA P STA considerObjects \ Clear bit 7 of considerObjects so GetTileAltitude will \ only extract the altitude and flatness of the tiles \ when we call it below, ignoring any objects on the \ landscape LDA #&7F \ Set the high byte of (Q P) = &7F00 STA Q \ \ This is the address where we will store the altitude \ data for the back row of tile corners in the landscape \ We now iterate through the tile corners with a nested \ loop, with zTile going from 31 to 0 (so that's from \ back to front) \ \ For each zTile, xTile also goes from 31 to 0, so \ that's from right to left \ \ So we work through the landscape, starting with the \ row of tile corners at the back (which we work through \ from right to left), and then doing the next row \ forward, looping until we reach the front row LDA #31 \ Set zTile = 31 so we start iterating from the back row STA zTile \ (so zTile iterates from 31 to 0 in the outer loop) .talt1 LDA #31 \ Set xTile = 31 so we start iterating from the right STA xTile \ end of the current row (so xTile iterates from 31 to 0 \ in the inner loop) BNE talt3 \ Jump to talt3 to join the loop below (this BNE is \ effectively a JMP as A is never zero) .talt2 JMP game10 \ Jump to MainTitleLoop to restart the game (this has \ nothing to do with the GetTileAltitudes routine, but \ is all part of the anti-cracker code) .talt3 JSR GetTileAltitude \ Call GetTileAltitude with bit 7 of considerObjects \ clear to extract the following tile data: \ \ * A = the high byte of the tile's altitude (which \ is also the altitude of the tile corner) \ \ * C flag = the tile's shape, clear if the tile is \ flat or set if the tile is not flat LDY xTile \ Set Y to the tile corner x-coordinate, to use as an \ index so we store the tile corner data like this: \ \ * Column xTile = 31 is stored in (Q P) + &1F \ * Column xTile = 30 is stored in (Q P) + &1E \ ... \ * Column xTile = 1 is stored in (Q P) + &01 \ * Column xTile = 0 is stored in (Q P) + &00 \ \ (Q P) starts at &7F00 for zTile = 31, so the back row \ of the landscape is stored in &7F00 to &7F1F \ \ (Q P) is decremented for each tile row (see below), so \ the next row forward is stored in &7E00 to &7E1F, for \ example ROL A \ Rotate the C flag into bit 0 of A, so we have the \ following: \ \ * Bit 0 = clear if the tile is flat or set if the \ tile is not flat \ \ * Bits 1-4 = the tile corner's altitude STA (P),Y \ Store the tile corner data in A in the Y-th entry in \ the variable at (Q P), so this populates the extracted \ data for the tile corner at (xTile, zTile) DEC xTile \ Decrement the tile corner x-coordinate in the inner \ loop BPL talt3 \ Loop back until we have processed all the tile corners \ in the tile row at z-coordinate zTile, working from \ right to left DEC Q \ Decrement the high byte of (Q P), so we store the \ tile corner data like this: \ \ * Row zTile = 31 is stored in &7F00 to &7F1F \ * Row zTile = 30 is stored in &7E00 to &7E1F \ ... \ * Row zTile = 1 is stored in &6100 to &611F \ * Row zTile = 0 is stored in &6000 to &601F DEC zTile \ Decrement the tile corner z-coordinate in the outer \ loop BPL talt1 \ Loop back until we have processed all the tile rows in \ the landscape, working from the back row of the \ landscape all the way to the front row \ \ This leaves (Q P) set to &6000 \ We now iterate through each tile to calculate the \ altitude of the highest tile corner, so we can store \ it after the altitude data that we just extracted LDA #&20 \ Set the low byte of (S R) = &20 STA R \ \ At this point the low byte of (Q P) is still zero, so \ the following loop will start with the following \ values: \ \ (Q P) = &7E00 \ \ (S R) = &7E20 \ \ In other words (Q P) points to the altitude data that \ we just extracted, and (S R) points to the next set of \ bytes just after the end of the altitude data \ We now work our way through the tiles, using X as the \ row number iterating from the rear, and Y as the \ column number iterating from right to left along each \ row in turn LDX #30 \ Set X = 30 to use as the row number, so we start \ iterating from the rear, skipping the row right at the \ back as the tile corners in that row do not anchor any \ tiles (so X iterates from 30 to 0 in the outer loop) .talt4 TXA \ Set A = &60 + X CLC \ ADC #&60 \ So this is the high byte of the address of the \ extracted altitude for row X, starting from &7E and \ working down to &60 as we iterate over each row STA Q \ Set the high byte of (Q P) to A, so (Q P) points to \ the extracted altitude data for row X STA S \ Set the high byte of (S R) to A, so (S R) points to \ the address just after the extracted altitude data \ for row X LDY #30 \ Set Y = 30 to use as the column number, so we start \ iterating from the right, skipping the rightmost \ column as the tile corners in that column do not \ anchor any tiles (so Y iterates from 30 to 0 in the \ inner loop) .talt5 \ We now calculate the altitude of the highest corner \ for the tile that we are analysing, i.e. the tile \ that's anchored by the tile corner at tile coordinates \ (X, Y) \ \ We do this by working through all four corners in the \ tile, starting with the anchor point, and then \ checking the corner to the right, then the corner \ behind, and then the corner to the left LDA (P),Y \ Fetch the extracted altitude data for the anchor of \ the tile that we are analysing LSR A \ Shift bit 0 into the C flag, so it contains the shape, \ and set A as the altitude BCC talt9 \ If the tile is flat then the C flag will be clear, so \ jump to talt9 to set (S R) to the altitude of the tile \ anchor, as the tile is flat and this altitude will do \ for the highest point on the tile ROL A \ Otherwise the tile is not flat, so rotate the C flag \ back into the extracted altitude data in A INY \ Increment Y to the tile corner to the right of the one \ we are analysing CMP (P),Y \ If this corner's altitude is less than the tile BCC talt6 \ anchor's altitude, jump to talt6 to skip the following LDA (P),Y \ Set A to the new corner's height, so that A contains \ the highest altitude of the tile's front two corners .talt6 INC Q \ Increment the high byte of (Q P), so it now points to \ the extracted altitude data for the row of tile \ corners behind the one we are currently analysing \ \ Y is still incremented from the anchor point, so this \ points us to the corner behind the one we just \ analysed CMP (P),Y \ If this corner's altitude is less than the highest BCC talt7 \ altitude, jump to talt7 to skip the following LDA (P),Y \ Set A to the new corner's height, so that A contains \ the highest altitude of the tile's front two corners \ and the one at the rear-right of the tile .talt7 DEY \ Decrement Y to the tile corner to the left of the one \ we just analysed CMP (P),Y \ If this corner's altitude is less than the highest BCC talt8 \ altitude, jump to talt8 to skip the following LDA (P),Y \ Set A to the new corner's height, so that A contains \ the highest altitude of the tile's front two corners \ and the two rear corners .talt8 DEC Q \ Decrement the high byte of (Q P) so it once again \ points to the extracted altitude data for the anchor \ point of the tile we are analysing LSR A \ Shift the highest altitude in A to remove the tile \ shape from bit 0 and set A to the actual altitude from \ bits 2 to 4 .talt9 STA (R),Y \ Set the entry in (S R) for this tile to the value in A \ so it contains the highest altitude of the tile \ anchored by the relevant tile corner DEY \ Decrement the column counter in Y to move left by one \ tile BPL talt5 \ Loop back until we have processed the whole row from \ right to left DEX \ Decrement the row counter in X to move forward by one \ row BPL talt4 \ Loop back to process the next row until we have \ processed all tiles in all rows in the landscape \ \ This leaves (S R) set to &6020 RTS \ Return from the subroutineName: GetTileAltitudes [Show more] Type: Subroutine Category: Drawing the landscape Summary: Calculate tile corner altitudes and maximum tile corner altitudes for each tile in the landscapeContext: See this subroutine in context in the source code References: This subroutine is called as follows: * GetTileVisibility calls GetTileAltitudes * CheckSecretStash calls via talt2
This routine calculates tile altitudes for use when drawing the landscape. The altitude of each tile corner and the shape of the anchored tile (if any) are stored as follows: * &6000 to &601F for row zTile = 0 * &6100 to &611F for row zTile = 1 ... * &7E00 to &7E1F for row zTile = 30 * &7F00 to &7F1F for row zTile = 31 The altitude of the highest tile corner for each tile is stored as follows: * &6020 to &603E for tile row anchored by zTile = 0 * &6120 to &613E for tile row anchored by zTile = 1 ... * &7D20 to &7E3E for tile row anchored by zTile = 29 * &7E20 to &7E3E for tile row anchored by zTile = 30
Returns: (Q P) (Q P) is set to &6000 (S R) (Q P) is set to &6020
Other entry points: talt2 Jump to MainTitleLoop via game10
[X]
Subroutine GetTileAltitude (category: Landscape)
Calculate the altitude of a tile, optionally including platform objects and trees in the calculation
[X]
Variable considerObjects in workspace Zero page
Controls whether the GetTileAltitude routine takes platform objects into consideration when calculating tile altitudes (bit 7) and returns details about the gaze vector (bit 6)
[X]
Entry point game10 in subroutine MainGameLoop (category: Main game loop)
Jump to MainTitleLoop to restart the game
[X]
Label talt1 is local to this routine
[X]
Label talt3 is local to this routine
[X]
Label talt4 is local to this routine
[X]
Label talt5 is local to this routine
[X]
Label talt6 is local to this routine
[X]
Label talt7 is local to this routine
[X]
Label talt8 is local to this routine
[X]
Label talt9 is local to this routine