Skip to navigation

Lander on the Acorn Archimedes

Particles: MoveAndDrawParticles (Part 1 of 4)

Name: MoveAndDrawParticles (Part 1 of 4) [Show more] Type: Subroutine Category: Particles Summary: Process particle movement and draw the particles into the graphics buffers, starting with the movement of particles Deep dive: Particles and particle clouds
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * LoseLife calls MoveAndDrawParticles * MainLoop calls MoveAndDrawParticles * DeleteParticleData calls via dpar1 * MoveAndDrawParticles (Part 2 of 4) calls via dpar1 * MoveAndDrawParticles (Part 3 of 4) calls via dpar1

Other entry points: dpar1 The start of the main particle-processing loop
.MoveAndDrawParticles STMFD R13!, {R10, R12, R14} \ Store the registers that we want to use on \ the stack so they can be preserved ADD R10, R11, #particleData \ Set R10 to the address of the particle \ data buffer, which we update as we work \ through the particle data buffer, so this \ points to the data of the particle being \ processed LDR R12, graphicsBuffEndAddr2 \ Set R1 to the address of the table that \ contains the end addresses of the graphics \ buffers \ We now work our way through the particle \ data buffer, processing each particle in \ turn .dpar1 LDMIA R10, {R0-R7} \ Fetch the eight words of particle data \ from the particle data buffer at R10, so \ this sets the following: \ \ (R0, R1, R2) = particle coordinate \ \ (R3, R4, R5) = particle velocity \ \ R6 = particle lifespan counter \ \ R7 = particle flags CMP R7, #0 \ If the last word of the data is zero, then LDMEQFD R13!, {R10, R12, PC} \ this is a null terminator and we have \ reached the end of the buffer, so retrieve \ the registers that we stored on the stack \ and return from the subroutine .dpar2 SUBS R6, R6, #1 \ Decrement the particle's lifespan counter \ in R6 BEQ DeleteParticleData \ If R6 is now zero then the particle just \ expired, so jump to DeleteParticleData to \ delete this particle from the particle \ data buffer \ \ DeleteParticleData then jumps back to \ dpar1 to move on to the next particle ADD R0, R0, R3 \ Move the particle by its current velocity ADD R1, R1, R4 \ by adding the particle's velocity vector ADD R2, R2, R5 \ in (R3, R4, R5) to the particle's \ coordinates in (R0, R1, R2) TST R7, #&00100000 \ If bit 20 of the particle flags is set, LDRNE R14, [R11, #gravity] \ add gravity to the velocity's y-coordinate ADDNE R4, R4, R14 \ in R4, so the particle accelerates towards \ the ground TST R7, #&00010000 \ If bit 16 of the particle flags is set, BLNE SetParticleColourToFade \ call SetParticleColourToFade to fade the \ particle colour from white to red, \ according to the particle's age, and store \ the colour in the bottom byte of the \ particle flags (bits 0 to 7) MOV R8, R0 \ Set (R8, R9) = (R0, R2) so we can fetch MOV R9, R2 \ the landscape altitude directly below the \ particle STMFD R13!, {R0-R3} \ Store R0 to R3 on the stack so they don't \ get corrupted by the following call to \ GetLandscapeAltitude BL GetLandscapeAltitude \ Set R0 to the altitude of the landscape at \ coordinates (x, z) = (R8, R9) MOV R9, R0 \ Copy the altitude into R9 LDMFD R13!, {R0-R3} \ Retrieve the values of R0 to R3 that we \ stored above TST R7, #&00200000 \ If bit 21 of the particle flags is set BLNE ProcessObjectDestruction \ then the particle can destroy objects that \ it hits, so call ProcessObjectDestruction \ to process this CMP R1, R9 \ If R1 > R9 then the particle is below the BLGT BounceParticle \ level of the landscape, so bounce the \ particle off the ground STMIA R10!, {R0-R7} \ Store the updated particle data in the \ particle data buffer, updating R10 so it \ points to the next particle, ready for the \ next iteration around the loop