Details of the tasks that Lander performs every iteration around the main loop
The main game loop in Lander is responsible for running the game-playing part of Lander (as opposed to the pre-game setup process or the part where we lose a life). Compared to some other games - Elite, I'm looking at you - the main loop in Lander is short and very easy to follow, as it simply calls the same set of subroutines on every iteration around the loop, and with very little extra logic.
The main loop is at MainLoop, and it does the following on every iteration:
- Check to see if the Escape key is being pressed, and if it is, quit the game and return to the Desktop or the command line, depending on how the game was originally run.
- Call MoveAndDrawPlayer to move the player's ship and draw it into the graphics buffers (see the deep dive on flying by mouse).
- Call CalculateRotationMatrix to build a rotation matrix from the value of the main loop counter, so we can use it to make the rocks tumble as they fall (see below).
- Call DropRocksFromTheSky to check whether the score is 800 or more, and if it is then consider dropping a rock from the sky, with higher scores making it more likely.
- Call MoveAndDrawParticles to move and draw all the particles, such as smoke clouds and bullets, into the graphics buffers (see the deep dive on particles and particle clouds).
- Call DrawObjects to draw all the 3D objects, such as trees and buildings, into the graphics buffers (see the deep dive on drawing 3D objects).
- Call AddTerminatorsToBuffers to add terminators to the ends of the graphics buffers so we know when to stop drawing (see the deep dive on depth-sorting with the graphics buffers).
- Call DrawLandscapeAndBuffers to draw the landscape and the contents of the graphics buffers (see the deep dive on drawing the landscape).
- Call PrintCurrentScore to print the number of remaining bullets at the left end of the score bar.
- Call DrawFuelLevel to draw the fuel bar.
- Call SwitchScreenBank to switch screen banks and clear the newly hidden screen bank to black (see the deep dive on screen memory in the Archimedes).
- Increment the main loop counter in mainLoopCount.
Most of this is pretty self-explanatory, and you can click on the deep dive links above for details of the more complicated steps in the main loop. Let's talk about the third step, though, as that's rather less obvious.
The rotation matrix
-------------------
In the third step of the main loop, we call CalculateRotationMatrix to build a rotation matrix from the value of the main loop counter. This matrix describes a rotation in two axes, with one axis rotating twice as fast as the other (as the two angles are set to mainLoopCount << 24 and mainLoopCount << 25). This means that any objects to which we apply this rotation matrix will rotate as we iterate around the main loop.
There are only three 3D objects that are set to rotate (see the deep dive on object blueprints for details). One is the player's ship, and for that we already have a rotation matrix based on the mouse position, which we calculated in the MoveAndDrawPlayer routine in step 2 of the main loop, so the counter-based rotation matrix does not apply there. The other two rotating objects are the pyramid and the rock, but the pyramid object is unused, so this leaves just the rock object. So as rocks fall from the sky, they are spun by the rotation matrix that is generated from the main loop counter, and this makes them tumble in the sky as they fall.
One final point to note about the main loop is that there is an almost identical copy of the loop in the LoseLife routine. This loop runs after we crash, so the explosion animation can run its course before we restart the game with the next life. This loop is just like the main loop, but without the calls to drop new rocks from the sky, draw the player's ship or update the fuel level, as we don't want any of these to happen once the player has crashed.
Instead of running endlessly, the LoseLife loop has its own counter in crashLoopCount, and when this runs out, so does the explosion animation (crashLoopCount is set to 30, so the animation runs for 30 frames before we move on to the next life).