.gpol9 LDA #0 \ Set yPolygonTop = 0 to record the y-coordinate of the STA yPolygonTop \ top of the polygon, where higher y-coordinates are up \ the screen (so this sets the top of the polygon to the \ bottom of the screen, so we can bump it up as we work \ through the polygon) STA xMaxHorizontal \ Set xMaxHorizontal = 0 so we can use it to keep track \ of the maximum x-coordinates of any polygon edges that \ are horizontal STA horizontalEdges \ Set horizontalEdges = 0 so we can use it to keep track \ of how many polygon edges are horizontal LDA #255 \ Set yPolygonBottom = 255 to record the y-coordinate of STA yPolygonBottom \ the bottom of the polygon, where higher y-coordinates \ are up the screen (so this sets the bottom of the \ polygon to the top of the screen, so we can move it \ down as we work through the polygon) STA xMinHorizontal \ Set xMinHorizontal = 255 so we can use it to keep \ track of the minimum x-coordinates of any polygon \ edges that are horizontal STA drawPolygon \ Set drawPolygon to a non-zero value, so by default the \ polygon will not be drawn, though we will set this to \ zero later if the polygon should be drawn LDY #0 \ We now loop through all the edges of the polygon, so \ set a loop counter in Y to work through all the edges \ of the polygon (three for a triangle, four for a \ quadrilateral) .gpol10 STY polygonEdge \ Store the polygon edge number that we are about to \ process in polygonEdge, so we can retrieve it at the \ end of the loop LDA (drawViewAngles),Y \ Set X to the offset within the drawing tables of the TAX \ Y-th point in the polygon INY \ Set Y to the offset within the drawing tables of the LDA (drawViewAngles),Y \ Y+1-st point in the polygon TAY \ So Y and X are the offsets within the drawing tables \ of the start and end points for the polygon edge that \ we are processing LDA #HI(xPolygonLeft) \ Set xPolygonAddrHi to the high byte of the address of STA xPolygonAddrHi \ the xPolygonLeft table, so this value can be used to \ modify the instructions for storing the polygon line \ x-coordinates as we process them \ \ The default is therefore to store the x-coordinate of \ the left end of the polygon line at xPolygonLeft LDA drawViewPitchLo,Y \ Set (A yEdgeDeltaLo) to the following: SEC \ SBC drawViewPitchLo,X \ drawViewPitch(Hi Lo) for point #Y STA yEdgeDeltaLo \ - drawViewPitch(Hi Lo) for point #X LDA drawViewPitchHi,Y \ SBC drawViewPitchHi,X \ So (A yEdgeDeltaLo) contains the difference in pitch \ angle between the two points, or the delta along the \ y-axis BPL gpol11 \ If the result in (A yEdgeDeltaLo) is positive then \ point #Y is higher than point #X and (A yEdgeDeltaLo) \ already has the correct sign for the absolute value, \ so jump to gpol11 to skip the following \ If we get here then point #X is higher than point #Y, \ so we swap them around STA yEdgeDeltaHi \ Set yEdgeDelta(Hi Lo) = (A yEdgeDeltaLo) INC xPolygonAddrHi \ Increment xPolygonAddrHi to HI(xPolygonRight), so when \ we modify the instructions for storing the polygon \ line x-coordinates, they are stored in the table for \ the right end of the polygon line at xPolygonRight STX T \ Swap X and Y around, so point #Y is now higher than STY U \ point #X LDX U LDY T LDA #0 \ Set (A yEdgeDeltaLo) = -yEdgeDelta(Hi Lo) SEC \ SBC yEdgeDeltaLo \ So yEdgeDelta(Hi Lo) is now positive STA yEdgeDeltaLo LDA #0 SBC yEdgeDeltaHi .gpol11 STA yEdgeDeltaHi \ Set yEdgeDelta(Hi Lo) = (A yEdgeDeltaLo) \ \ So point #Y is higher than point #X, and we have a \ positive value in yEdgeDelta(Hi Lo) that contains the \ y-axis delta between the two points \ \ Also, xPolygonAddrHi points to the correct table for \ storing the polygon line (left or right) BIT xPolygonPointScale \ If bit 6 of xPolygonPointScale is clear then the pixel BVC gpol13 \ x-coordinates of all the polygon points fit into \ single-byte numbers, so jump to gpol13 to process the \ edge accordingly LDA xPolygonPointHi,Y \ If both of the high bytes for point #X and point #Y ORA xPolygonPointHi,X \ are zero then the x-coordinates for these particular BEQ gpol13 \ points happen to fit into single-byte numbers, so \ jump to gpol13 to process the edge accordingly LDA yEdgeDeltaHi \ If yEdgeDeltaHi is non-zero then the y-axis delta is BNE gpol12 \ non-zero, so jump to part 6 via gpol12 to process the \ edge accordingly LDA yEdgeDeltaLo \ If yEdgeDeltaLo = 0 then we know yEdgeDelta(Hi Lo) BEQ gpol15 \ must be zero as we passed through the BNE above, so \ the polygon edge is horizontal and we jump to gpol15 \ to move on to the next polygon edge .gpol12 JMP gpol22 \ If we get here then: \ \ * The x-coordinates for points #X and #Y are both \ two-byte numbers \ \ * The y-axis delta in yEdgeDelta(Hi Lo) is non-zero \ and positive \ \ So we jump to part 6 to process this edge accordingly .gpol13 \ If we get here then the x-coordinates for points #X \ and #Y fit into single-byte numbers LDA yEdgeDeltaHi \ If yEdgeDeltaHi is zero then the y-axis delta also BEQ gpol14 \ fits into a single-byte number, so jump to gpol14 LDA #0 \ Zero the high bytes for both points' x-coordinates, STA xPolygonPointHi,Y \ because we are about to process the edge using STA xPolygonPointHi,X \ two-byte calculations, and the high bytes don't get \ written when the x-coordinates of all the polygon \ points fit into single-byte numbers \ \ So this just ensures that the high bytes are correctly \ set up so we can use the value of xPolygonPoint(Hi Lo) \ in the calculations and get the correct x-coordinate \ values JMP gpol22 \ If we get here then: \ \ * The x-coordinates for points #X and #Y are both \ single-byte numbers \ \ * The x-coordinates for points #X and #Y have had \ their high bytes zeroed so they can be used as \ two-byte numbers \ \ * The y-axis delta in yEdgeDelta(Hi Lo) is a \ two-byte number that is non-zero and positive \ \ So we jump to part 6 to process this edge accordingly .gpol14 \ If we get here then: \ \ * The x-coordinates for points #X and #Y are both \ single-byte numbers \ \ * The y-axis delta in yEdgeDelta(Hi Lo) is a \ single-byte number and is therefore equal to \ yEdgeDeltaLo LDA yEdgeDeltaLo \ If yEdgeDeltaLo = 0 then yEdgeDelta(Hi Lo) = 0, so BEQ gpol19 \ jump to gpol19 to process this \ We now set up the start and end points so that the \ edge is either horizontal or slopes downwards when \ moving from the start to the end, as that's what the \ TracePolygonEdge routine expects \ \ We know that point #Y is higher than point #X as we \ set that up above, so we trace along the line from \ the start at point #Y to the end at point #X LDA drawViewPitchHi,Y \ Set yEdgeStart(Hi Lo) = drawViewPitch(Hi Lo) STA yEdgeStartHi \ LDA drawViewPitchLo,Y \ So this sets the y-coordinate of the start point in STA yEdgeStartLo \ point #Y (the lower point) LDA drawViewPitchHi,X \ Set yEdgeEnd(Hi Lo) = drawViewPitch(Hi Lo) STA yEdgeEndHi \ LDA drawViewPitchLo,X \ So this sets the y-coordinate of the end point in STA yEdgeEndLo \ point #X (the higher point) LDA xPolygonPointLo,Y \ Set xEdgeStart(Hi Lo) = (0 xPolygonPointLo) STA xEdgeStartLo \ \ So this sets the x-coordinate of the start point in \ point #Y (the lower point), starting with the low \ bytes LDA xPolygonPointLo,X \ Set xEdgeEnd(Hi Lo) = (0 xPolygonPointLo) STA xEdgeEndLo \ \ So this sets the x-coordinate of the start point in \ point #Y (the lower point), starting with the low \ bytes LDA #0 \ Zero the high bytes of xEdgeStart(Hi Lo) and STA xEdgeStartHi \ xEdgeEnd(Hi Lo) STA xEdgeEndHi JSR TracePolygonEdge \ Trace the polygon edge, populating the xPolygonRight \ or xPolygonLeft table with the x-coordinate of the \ edge for each y-coordinate .gpol15 \ We now move on to the next edge in the polygon LDY polygonEdge \ Set Y to the number of the polygon edge that we have \ been processing INY \ Increment Y to move on to the next edge in the polygon CPY polygonEdgeCount \ If we have processed all the edges in the polygon then BEQ gpol16 \ jump to gpol16 to keep going JMP gpol10 \ Otherwise loop back to gpol10 to process the next edge \ in the polygon .gpol16 \ We have processed all the edges in the polygon, so now \ we work out whether the polygon is visible in the \ current screen buffer LDA horizontalEdges \ If horizontalEdges does not match polygonEdgeCount CMP polygonEdgeCount \ then not every edge in the polygon was horizontal, so BNE gpol17 \ jump to gpol17 to skip the following \ If we get here then every edge in the polygon is \ horizontal, so the entire polygon appears within a \ single horizontal line LDA drawViewPitchHi,X \ If the high byte of the view-relative pitch angle for BNE gpol17 \ point #X is non-zero then point #X is definitely not \ on-screen, and so neither is the horizontal line, so \ jump to gpol17 to skip the following LDY drawViewPitchLo,X \ Set Y to the low byte of the view-relative pitch angle \ for point #X (and therefore the pitch angle for the \ horizontal line) CPY minPitchAngle \ If Y < minPitchAngle then the line is not within the BCC gpol17 \ screen buffer as the pitch angle is below the minimum \ value in the buffer, so jump to gpol17 to skip the \ following CPY maxPitchAngle \ If Y >= maxPitchAngle hen the line is not within the BCS gpol17 \ screen buffer as the pitch angle is above the maximum \ value in the buffer, so jump to gpol17 to skip the \ following \ If we get here then the polygon is a single horizontal \ line and it appears within the screen buffer, so we \ configure the result to return a single polygon line \ with the y-coordinate of single horizontal line, and \ with the maximum and minimum x-coordinates that we \ have been calculating in xMinHorizontal and \ xMaxHorizontal STY yPolygonBottom \ Set both the top and bottom polygon y-coordinates to STY yPolygonTop \ the low byte of the view-relative pitch angle for \ point #X LDA xMinHorizontal \ Set the left edge of the polygon line to the STA xPolygonLeft,Y \ x-coordinate in xMinHorizontal LDA xMaxHorizontal \ Set the right edge of the polygon line to the STA xPolygonRight,Y \ x-coordinate in xMaxHorizontal LDA #0 \ Set drawPolygon = 0 so the polygon gets drawn STA drawPolygon .gpol17 LDA drawPolygon \ If drawPolygon is non-zero then the polygon should not BNE gpol18 \ be drawn, so jump to gpol18 to return from the \ subroutine with the C flag set LDA yPolygonTop \ If yPolygonTop < yPolygonBottom then there are no CMP yPolygonBottom \ visible lines to draw in the polygon, so jump to BCC gpol18 \ gpol18 to return from the subroutine with the C flag \ set CLC \ Clear the C flag to indicate that the polygon is \ visible in the current screen buffer and should be \ drawn RTS \ Return from the subroutine .gpol18 SEC \ Set the C flag to indicate that the polygon is not \ visible in the current screen buffer and should not be \ drawn RTS \ Return from the subroutine .gpol19 \ If we get here then yEdgeDelta(Hi Lo) = 0, so this \ polygon edge is horizontal LDA xPolygonPointLo,X \ Set A = xPolygonPointLo for point #X CMP xMaxHorizontal \ Set xMaxHorizontal = max(xMaxHorizontal, A) BCC gpol20 \ STA xMaxHorizontal \ So xMaxHorizontal keeps track of the maximum \ x-coordinate of all the horizontal polygon edges .gpol20 CMP xMinHorizontal \ Set xMinHorizontal = min(xMinHorizontal, A) BCS gpol21 \ STA xMinHorizontal \ So xMinHorizontal keeps track of the minimum \ x-coordinate of all the horizontal polygon edges .gpol21 INC horizontalEdges \ Increment horizontalEdges so we keep a count of all \ the horizontal polygon edges JMP gpol15 \ Jump to gpol15 to move on to the next polygon edgeName: GetPolygonLines (Part 5 of 6) [Show more] Type: Subroutine Category: Drawing polygons Summary: Loop through all the edges in the polygon and call the correct routines to process one-byte, two-byte or horizontal edgesContext: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
[X]
Subroutine TracePolygonEdge (Part 1 of 8) (category: Drawing polygons)
Trace a polygon edge, populating xPolygonRight or xPolygonLeft with the x-coordinate of the edge for each y-coordinate
[X]
Variable drawPolygon in workspace Zero page
A flag to record whether the polygon we are currently processing contains any visible pixels, so it can be used to control whether we actually draw the polygon
[X]
Variable drawViewAngles in workspace Zero page
The address in drawViewAngles(1 0) of the pitch and yaw angles of the tile and polygon points that we are drawing in the landscape view
[X]
Variable drawViewPitchHi (category: Drawing the landscape)
Storage for the pitch angles of tiles and object points for drawing the current landscape view (high bytes)
[X]
Variable drawViewPitchLo (category: Drawing the landscape)
Storage for the pitch angles of tiles and object points for drawing the current landscape view (low bytes)
[X]
Label gpol10 is local to this routine
[X]
Label gpol11 is local to this routine
[X]
Label gpol12 is local to this routine
[X]
Label gpol13 is local to this routine
[X]
Label gpol14 is local to this routine
[X]
Label gpol15 is local to this routine
[X]
Label gpol16 is local to this routine
[X]
Label gpol17 is local to this routine
[X]
Label gpol18 is local to this routine
[X]
Label gpol19 is local to this routine
[X]
Label gpol20 is local to this routine
[X]
Label gpol21 is local to this routine
[X]
Label gpol22 in subroutine GetPolygonLines (Part 6 of 6)
[X]
Variable horizontalEdges in workspace Zero page
A counter to keep track of how many polygon edges are horizontal in the polygon we are drawing
[X]
Variable maxPitchAngle in workspace Zero page
The maximum pitch angle that fits into the current screen buffer
[X]
Variable minPitchAngle in workspace Zero page
The minimum pitch angle that fits into the current screen buffer
[X]
Variable polygonEdge in workspace Zero page
The number the side of the polygon that we are currently processing
[X]
Variable polygonEdgeCount in workspace Zero page
The number of sides in the polygon we are drawing, which is one less than the number of points in the polygon's point list (as the last point in the list is always a repeat of the first point)
[X]
Variable xEdgeEndHi in workspace Zero page
The x-coordinate of the end point in the polygon edge being processed (high byte)
[X]
Variable xEdgeEndLo in workspace Zero page
The x-coordinate of the end point in the polygon edge being processed (low byte)
[X]
Variable xEdgeStartHi in workspace Zero page
The x-coordinate of the start point in the polygon edge being processed (high byte)
[X]
Variable xEdgeStartLo in workspace Zero page
The x-coordinate of the start point in the polygon edge being processed (low byte)
[X]
Variable xMaxHorizontal in workspace Zero page
A variable to keep track of the maximum x-coordinates of any polygon edges that are horizontal in the polygon we are drawing
[X]
Variable xMinHorizontal in workspace Zero page
A variable to keep track of the minimum x-coordinates of any polygon edges that are horizontal in the polygon we are drawing
[X]
Variable xPolygonAddrHi in workspace Zero page
The high byte of the address of the table where we store the x-coordinate of the polygon line being processed, so this is either HI(xPolygonLeft) or HI(xPolygonRight)
[X]
Variable xPolygonLeft (category: Drawing polygons)
The pixel x-coordinate of the left edge of each pixel line in the polygon being drawn
[X]
Variable xPolygonPointHi (category: Drawing polygons)
Pixel x-coordinates for all the points in the polygon that we are currently drawing (high bytes)
[X]
Variable xPolygonPointLo (category: Drawing polygons)
Pixel x-coordinates for all the points in the polygon that we are currently drawing (low bytes)
[X]
Variable xPolygonPointScale in workspace Zero page
A flag to record whether the pixel x-coordinate of the polygon points being processed fit into one or two bytes
[X]
Variable xPolygonRight (category: Drawing polygons)
The pixel x-coordinate of the right edge of each pixel line in the polygon being drawn
[X]
Variable yEdgeDeltaHi in workspace Zero page
The difference in pitch angle between two polygon points, i.e. the delta along the y-axis (high byte)
[X]
Variable yEdgeDeltaLo in workspace Zero page
The difference in pitch angle between two polygon points, i.e. the delta along the y-axis (low byte)
[X]
Variable yEdgeEndHi in workspace Zero page
The y-coordinate of the end point in the polygon edge being processed (high byte)
[X]
Variable yEdgeEndLo in workspace Zero page
The y-coordinate of the end point in the polygon edge being processed (low byte)
[X]
Variable yEdgeStartHi in workspace Zero page
The y-coordinate of the start point in the polygon edge being processed (high byte)
[X]
Variable yEdgeStartLo in workspace Zero page
The y-coordinate of the start point in the polygon edge being processed (low byte)
[X]
Variable yPolygonBottom in workspace Zero page
The y-coordinate of the bottom of the polygon being drawn (where higher y-coordinates are up the screen)
[X]
Variable yPolygonTop in workspace Zero page
The y-coordinate of the top of the polygon being drawn (where higher y-coordinates are up the screen)