Skip to navigation

Lander on the Acorn Archimedes

Drawing triangles: DrawTriangleShadowToBuffer

Name: DrawTriangleShadowToBuffer [Show more] Type: Subroutine Category: Drawing triangles Summary: Draw a triangle shadow into the correct graphics buffer, according to its distance Deep dive: Drawing 3D objects Depth-sorting with the graphics buffers Drawing triangles
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DrawObject (Part 4 of 5) calls DrawTriangleShadowToBuffer

This command draws a triangle into a graphics buffer, with the buffer being chosen according to the distance of the triangle in the z-axis. This command is used for drawing triangle shadows, while the triangles themselves are drawn by DrawTriangleToBuffer. It is always called with a colour value of 0 in R8, so shadows are always black. The command number for drawing a triangle is 18, followed by seven parameter words that match the arguments for the DrawTriangle routine: * Command number (18) * Pixel coordinate of corner 1 (x1, y1) * Pixel coordinate of corner 2 (x2, y2) * Pixel coordinate of corner 3 (x3, y3) * Colour
Arguments: (R0, R1) Pixel coordinate of corner 1 (R2, R2) Pixel coordinate of corner 2 (R4, R5) Pixel coordinate of corner 4 R8 Colour (always 0 for black) R12 The address of the table of containing the end addresses of the graphics buffers (i.e. graphicsBuffersEnd)
Returns: R12 R12 is preserved
.DrawTriangleShadowToBuffer STMFD R13!, {R9, R14} \ Store the registers that we want to use on \ the stack so they can be preserved LDR R14, [R11, #zObject] \ Set R14 to the z-coordinate of the \ triangle RSB R14, R14, #LANDSCAPE_Z \ Set R14 = landscape offset - R14 \ \ We use the top byte of this number as the \ number of the graphics buffer to draw into \ \ This ensures that more distant triangles \ are drawn into lower-numbered graphics \ buffers, so higher z-coordinates map to \ lower buffer numbers and vice versa (so \ buffer 0 is for objects that are far away \ and buffer 10 is for the closest objects \ to the viewer) CMP R14, #LANDSCAPE_Z_BEYOND \ If R14 is a z-distance beyond the back of MOVHS R14, #LANDSCAPE_Z_DEPTH \ the visible landscape, cap it to the depth \ of the landscape so it fits into the range \ of graphics buffers (as there is one \ buffer for each tile row, going into the \ screen) BIC R14, R14, #&00C00000 \ We are going to use the top byte of R14 as \ the buffer number, and we're going to look \ up the corresponding buffer address from a \ lookup table with four bytes per entry, so \ we clear bits 22 and 23 to ensure that \ R14 >> 22 contains the value of the top \ byte * 4, which we can then use as an \ offset into the lookup table to fetch the \ address of the end of the buffer, which is \ where we can store our triangle-drawing \ command LDR R9, [R12, R14, LSR #22] \ Set R9 to the address of the next free \ byte in the graphics buffer whose number \ matches the top byte of R14, fetching the \ address from the lookup table at R12 MOV R7, #18 \ The command number for drawing a triangle STR R7, [R9], #4 \ is 18, so we store a value of 18 in the \ graphics buffer and increment the address \ in R9 to point to the next word in the \ buffer (see bufferJump for a full list of \ drawing commands) STMIA R9!, {R0-R5, R8} \ Store the three pixel coordinates from R0 \ to R5, and then the colour in R8, in the \ buffer STR R9, [R12, R14, LSR #22] \ Update the end address in the table at R12 \ to point to the new end address of the \ graphics buffer LDMFD R13!, {R9, PC} \ Retrieve the registers that we stored on \ the stack and return from the subroutine