\ We have calculated the yaw angle of the vector from \ the viewer to the tile corner we are analysing, so \ now for the pitch angle \ \ We start by fetching the tile data for the tile corner \ we are analysing, and for that we need to know the \ tile coordinates in terms of the 3D world, as that's \ how the tileData table is organised \ \ The following code sets (X, Y) to the coordinate of \ the tile corner we are analysing, i.e. (xTile, zTile), \ but with the axes rotated to match the orientation of \ the 3D world rather than the viewer (as xTile and \ zTile contain the coordinates from the perspective of \ the viewer, not the 3D world) \ \ This is the reverse of the process described in part 1 \ of the DrawLandscapeView routine, which changes the \ frame of reference from the 3D world to the viewer \ \ In that routine, we map the following coordinate \ changes, depending on the direction in which the \ viewer is facing compared to the 3D world's default \ axes: \ \ * If the viewer has not turned: \ (x, z) maps to (x, z) \ \ * If the viewer has turned right: \ (x, z) maps to (30 - z, x) \ \ * If the viewer has turned around: \ (x, z) maps to (30 - x, 30 - z) \ \ * If the viewer has turned left: \ (x, z) maps to (z, 30 - x) \ \ So we apply the same logic here, but in the reverse \ direction, as we want to move from the viewer's frame \ of reference into the 3D world's frame of reference \ \ Note that the logic in DrawLandscapeView subtracts \ from 30, while here we subtract from 31, because this \ logic is working with tile corners, while the logic in \ DrawLandscapeView is working with tiles BIT viewingArcRightYaw \ If bit 7 of the quadrant containing the right edge of BMI tang4 \ the viewing arc is set, jump to tang4 BVS tang3 \ If bit 6 of the quadrant containing the right edge of \ the viewing arc is set, jump to tang3 \ If we get here then: \ \ * Bit 7 of the right edge's quadrant is clear \ * Bit 6 of the right edge's quadrant is clear \ \ This means that the right edge of the viewing arc is \ in the 12 o'clock to 3 o'clock quadrant \ \ This means that the viewer has not turned, so we can \ use the tile coordinates unchanged LDX xTile \ Set X = xTile LDY zTile \ Set Y = zTile JMP tang6 \ Jump to tang6 to keep going .tang3 \ If we get here then: \ \ * Bit 7 of the right edge's quadrant is clear \ * Bit 6 of the right edge's quadrant is set \ \ This means that the right edge of the viewing arc is \ in the 3 o'clock to 6 o'clock quadrant \ \ This means that the viewer has turned right, so we can \ turn left to go back to the 3D world \ \ Turning left maps (x, z) maps to (z, 31 - x), so \ that's what we do now LDX zTile \ Set X = zTile LDA #31 \ Set Y = 31 - xTile SEC SBC xTile TAY JMP tang6 \ Jump to tang6 to keep going .tang4 \ If we get here then bit 7 of the quadrant containing \ the right edge of the viewing arc is set BVS tang5 \ If bit 6 of the quadrant containing the right edge of \ the viewing arc is set, jump to tang5 \ If we get here then: \ \ * Bit 7 of the right edge's quadrant is set \ * Bit 6 of the right edge's quadrant is clear \ \ This means that the viewer has turned around, so we \ turn back around to go back to the 3D world \ \ Turning around maps (x, z) maps to (31 - x, 31 - z), \ so that's what we do now LDA #31 \ Set X = 31 - xTile SEC SBC xTile TAX LDA #31 \ Set Y = 31 - zTile SEC SBC zTile TAY JMP tang6 \ Jump to tang6 to keep going .tang5 \ If we get here then: \ \ * Bit 7 of the right edge's quadrant is set \ * Bit 6 of the right edge's quadrant is set \ \ This means that the right edge of the viewing arc is \ in the 9 o'clock to 12 o'clock quadrant \ \ This means that the viewer has turned left, so we can \ turn right to go back to the 3D world \ \ Turning right maps (x, z) maps to (31 - z, x), so \ that's what we do now LDA #31 \ Set X = 31 - xTile SEC SBC zTile TAX LDY xTile \ Set Y = yTile .tang6 \ We now have the tile coordinates for the tile that we \ are analysing, but in 3D world coordinates, so we can \ now fetch the tile data \ \ The 3D world coordinates for the tile are in (X, Y), \ so we can fetch the tile data using code that's very \ similar to the GetTileData routine \ \ In the following comments I will refer to (X, Y) as \ (xTile, zTile), just as in GetTileData, as that's a \ bit easier to follow than X and Y STY T \ Store zTile in T, so we can use it in the following \ calculation TXA \ Set Y = (xTile << 3 and %11100000) + zTile ASL A \ = (xTile >> 2 and %00000111) << 5 + zTile ASL A \ = (xTile div 4) * &20 + zTile ASL A AND #%11100000 ORA T TAY TXA \ Set A = bits 0-1 of xTile AND #%00000011 \ = xTile mod 4 STA T \ Store A in T so we can use it in part 3 to calculate \ the address of the tile's visibility bit \ The low byte of tileDataPage(1 0) gets set to zero in \ ResetVariables and is never changed \ \ The low byte of tileData is also zero, as we know that \ tileData is &0400 \ \ So in the following, we are just adding the high bytes \ to get a result that is on a page boundary CLC \ Set the following: ADC #HI(tileData) \ STA tileDataPage+1 \ tileDataPage(1 0) = tileData + (A 0) \ = tileData + (xTile mod 4) * &100 \ So we now have the following: \ \ tileDataPage(1 0) = tileData + (xTile mod 4) * &100 \ \ Y = (xTile div 4) * &20 + zTile \ \ The address in tileDataPage(1 0) is the page within \ tileData for the tile anchored at (xTile, zTile), and \ is always one of &0400, &0500, &0600 or &0700 because \ (xTile mod 4) is one of 0, 1, 2 or 3 \ \ The value of Y is the offset within that page of the \ tile data for the tile anchored at (xTile, zTile) \ \ We can therefore fetch the tile data for the specified \ tile using Y as an index offset from tileDataPage(1 0) LDA (tileDataPage),Y \ Set A to the tile data for the tile anchored at \ (xTile, zTile) LDX drawingTableIndex \ Store the tile data in the correct place in the STA tileViewData,X \ tileViewData table \ Fall through into part 3 to finish the pitch angle \ calculationsName: GetTileViewAngles (Part 2 of 4) [Show more] Type: Subroutine Category: Drawing the landscape Summary: Fetch the tile data for the tile corner we are analysingContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
[X]
Variable drawingTableIndex in workspace Zero page
The index into the drawing tables for the tile being analysed
[X]
Label tang3 is local to this routine
[X]
Label tang4 is local to this routine
[X]
Label tang5 is local to this routine
[X]
Label tang6 is local to this routine
[X]
Variable tileData (category: Landscape)
Altitude and shape data for landscape tiles
[X]
Variable tileDataPage in workspace Zero page
The address of the tileData page containing the current tile's data
[X]
Variable tileViewData in workspace Stack variables
The tile data for tiles in the current landscape view
[X]
Variable viewingArcRightYaw in workspace Zero page
The yaw angle of the right edge of the viewing arc, where the arc is 90 degrees wide