Skip to navigation

Lander on the Acorn Archimedes

Drawing triangles: DrawTriangle (Part 9 of 11)

Name: DrawTriangle (Part 9 of 11) [Show more] Type: Subroutine Category: Drawing triangles Summary: Draw the top part of a clipped triangle Deep dive: Drawing triangles
Context: See this subroutine in context in the source code References: No direct references to this subroutine in this source file
\ By this point we have the following: \ \ (R0, R1) = (x3, y3) \ \ (R2, R3) = (x2, y2) \ \ R4 = x-coordinate of the left edge for \ the last line that we drew \ \ R5 = x-coordinate of the right edge for \ the last line that we drew \ \ R7 = (y1 - y3) / (x3 - x1) \ = slope of (x1, y1) to (x3, y3) \ \ R12 = (y2 - y3) / (x3 - x2) \ = slope of (x2, y2) to (x3, y3) SUB R9, R3, R1 \ Set R9 = R3 - R1 \ = y2 - y3 \ \ So this is the vertical distance between \ (x2, y2) and (x3, y3), i.e. the delta \ y-coordinate between the two points \ \ We know this is positive because y2 >= y3, \ so we can use this as a loop counter for \ drawing horizontal lines in the triangle \ between y-coordinates y2 and y3 \ The following calculations are very \ similar to those in part 4 for the \ unclipped triangle, but the shifts keep \ the sign of the shifted register (they use \ ASR instead of LSR) SUBS R14, R2, R4, ASR #16 \ Set: \ \ R14 = R2 - R4 >> 16 \ = x2 - left edge of horizontal line \ \ So this will be zero if (x2, y2) is at the \ left edge of the horizontal line SUBNES R10, R2, R5, ASR #16 \ If the above is non-zero, set: \ \ R10 = R2 - R5 >> 16 \ = x2 - right edge of horizontal line \ \ So this will be zero if (x2, y2) is at the \ right edge of the horizontal line BNE trin37 \ If both of the above are non-zero, jump to \ trin37, as (x2, y2) doesn't match either \ edge of the horizontal line we just drew CMP R2, R4, ASR #16 \ Set the flags on R2 - R4 >> 16 MOVEQ R6, R12 \ If R2 = R4 >> 16, then x2 = left edge, so: BICEQ R4, R4, #&FF00 \ so x2 must be at the left edge, so we set BICEQ R4, R4, #&00FF \ the slope of the left edge in R6 to R12, ORREQ R4, R4, #&8000 \ as it's the left edge that is changing \ slope as we move into the top part of the \ triangle: \ \ R6 = R12 \ = slope of (x2, y2) to (x3, y3) \ \ We also reset the fractional part of R4 \ (the left edge x-coordinate) to just the \ top bit set (so that's 0.5) \ \ So this sets the slope of the left edge \ and leaves the slope of the right edge as \ before MOVNE R7, R12 \ If R2 <> R4 >> 16, then x2 <> left edge, BICNE R5, R5, #&FF00 \ so x2 must be at the right edge, so we set BICNE R5, R5, #&00FF \ the slope of the right edge in R7 to R12, ORRNE R5, R5, #&8000 \ as it's the right edge that is changing \ slope as we move into the top part of the \ triangle: \ \ R7 = R12 \ = slope of (x2, y2) to (x3, y3) \ \ We also reset the fractional part of R5 \ (the right edge x-coordinate) to just the \ top bit set (so that's 0.5) \ \ So this sets the slope of the right edge \ and leaves the slope of the left edge as \ before .trin36 LDR R12, screenAddr \ Set R12 to the address of the screen bank \ we are drawing in, pointing just below \ the two lines of text at the top of the \ screen BL trin45 \ Call the subroutine in part 11 to draw the \ top part of the triangle, clipping it to \ the screen as we go LDMFD R13!, {PC} \ Return from the subroutine .trin37 \ We jump here following these two \ calculations, if neither of them are zero: \ \ R14 = R2 - R4 >> 16 \ = x2 - left edge of horizontal line \ \ R10 = R2 - R5 >> 16 \ = x2 - right edge of horizontal line \ \ I am not sure what this signifies! RSBMI R10, R10, #0 \ The last calculation was for R10, so this \ makes R10 positive if the above result is \ negative, so it does this: \ \ R10 = |R10| CMP R14, #0 \ Set the following: RSBMI R14, R14, #0 \ \ R14 = |R14| \ So R10 and R14 are set to the magnitudes \ of the distances between (x2, y2) and each \ edge of the horizontal line (R14 for left, \ R10 for right) CMP R14, R10 \ If |R14| >= |R10| then (x2, y2) is nearer MOVHS R6, R12 \ the right edge, so set: \ \ R6 = R12 \ = slope of (x2, y2) to (x3, y3) \ \ So this sets the slope of the left edge \ and leaves the slope of the right edge as \ before (though I'm not sure why?) MOVLO R7, R12 \ Otherwise |R14| < |R10| and (x2, y2) is \ nearer the left edge, so set: \ \ R7 = R12 \ = slope of (x2, y2) to (x3, y3) \ \ So this sets the slope of the right edge \ and leaves the slope of the left edge as \ before (though I'm not sure why?) B trin36 \ Jump up to trin14 to draw the top part of \ the triangle