Skip to navigation

Lander on the Acorn Archimedes

Particles: DrawParticleShadowToBuffer

Name: DrawParticleShadowToBuffer [Show more] Type: Subroutine Category: Particles Summary: Draw a small black particle into the correct graphics buffer, according to its distance Deep dive: Depth-sorting with the graphics buffers
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * MoveAndDrawParticles (Part 4 of 4) calls DrawParticleShadowToBuffer

This command draws a small black particle into a graphics buffer, with the buffer being chosen according to the distance of the particle in the z-axis. This command is used for drawing particle shadows, while the particles themselves are drawn by DrawParticleToBuffer. The command numbers for drawing small particles are 9 to 17, with higher numbers giving smaller particles (so particles are smaller when they are further away, as the command number is based on the z-coordinate). This is followed by the pixel coordinates, composed into one 32-bit parameter word as follows: #20-31 #12-19 #8-11 #0-7 019876543210 98765432 1098 76543210 ^ ^ ^ ^ | | | | Pixel x-coord Colour Unused Pixel y-coord (0-319) (always 0) (0-255)
Arguments: (R0, R1) The pixel coordinate of the particle R8 The 3D z-coordinate of the particle R12 The address of the table of containing the end addresses of the graphics buffers (i.e. graphicsBuffersEnd)
Returns: R12 R12 is preserved
.DrawParticleShadowToBuffer STMFD R13!, {R9, R14} \ Store the registers that we want to use on \ the stack so they can be preserved RSB R14, R8, #LANDSCAPE_Z \ Set R14 = landscape offset - R8 \ \ We use the top byte of this number as the \ number of the graphics buffer to draw into \ \ This ensures that more distant particles \ 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) 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 particle-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 R8, R8, LSR #25 \ Scale R8 from a 3D z-coordinate into a CMP R8, #8 \ number between 9 and 17, which we can use MOVHS R8, #8 \ as the drawing command number, as drawing ADD R8, R8, #9 \ commands 9 to 17 draw shadow particles \ with higher numbers giving smaller \ particles (see bufferJump for a full list \ of drawing commands) ADD R1, R1, R0, LSL #20 \ Encode the two pixel coordinates in R0 and \ R1 into one parameter word in R1, by \ inserting the value of R0 into bits 20-31 \ of R1 \ \ The colour in bits 12-19 is left at zero, \ so the particle is always black STR R8, [R9], #4 \ Store the drawing command number in the \ graphics buffer and increment the address \ in R9 to point to the next word in the \ buffer STR R1, [R9], #4 \ Store the parameter word in R1 in the \ graphics buffer and increment the address \ in R9 to point to the next word 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