Chapter 20 - May 16th, 2015
The transfer to the tile based terrain scroller went better than I had expected and now it was time to get my plane up and into the air. But getting this plane off the ground had it's fair share of challenges I had to contend with.
Challenge No. 1
The player's plane sprite had to operate in the dual display pane (double buffer), 1 byte scroll architecture of the game. The problem stemmed from the way the CoCo3's GIME chip handles the horizontal virtual enable feature.
To recap, when horizontal virtual is enabled, the GIME creates a bitmap that is 256 bytes wide but only displays 160 bytes (when using a 320 resolution). A 7-bit value is used to position this 160 byte window anywhere along this 256 byte map (in 2 byte intervals). The GIME generates video from this point but when in reaches the end of the 256 byte boundary, it restarts again at the 0 boundary on the same line and continues as before. This is actually advantageous for horizontal scrolling but is unlike how RAM is mapped where the byte immediately after the 256 byte boundary continues with the next byte on the next scanline.
It gets tricky when drawing my plane sprite, which must physically move against the scrolling so as to remain in a fixed position on the screen. When it reaches this 256 byte boundary, I have to compensate the scanline offset when half of the plane sprite is drawn before the 256 byte boundary while the remaining half is drawn after the 256 byte boundary. Writing data in a conventional method would wrap half the plane down a scanline.
The solution was to draw the graphics in vertical strips and utilizing an 8-bit register to track the offset from 0 for each strip. An 8-bit register will roll over back to 0 once it passes 255 and this complemented the GIME horizontal virtual mode of operation.
Challenge No. 2
The second challenge was to reduce the CPU cycle penalty that comes with the solution of the first challenge. I intially wrote a normal block of code to place the sprite in this vertical-strip process but found it was taking way too many CPU cycles. I'm concious how much time is being taken up by every routine in the main game loop in order to allow time for the other routines which are yet to follow. My goal was to have the game loop code running at 30 frames-per-second and this routine was simply not going to allow that to happen later down the track.
The solution was loop unrolling (explained in Chapter 12). I broke the loop down to individual lines of code and wrote data directly from the code instead of reading data from a table or graphics area. The routine immediately blew out in size but the resultant speed boost was immense and I was back on track.
Challenge No. 3
The last challenge was incorporating the user's controls for the plane sprite. It had to be navigatable in 8 directions... up, down, left, right as well as the 4 diagonals in between.
Keyboard was my first thought but joystick control was the easiest to use and the more logical control mechanism for this game. I tailored my routine to use the self centering Tandy Deluxe Joystick and ignored the free floating black joysticks that Tandy sold. These joysticks are unsuitable for this style of game. The lack of self centering makes it very hard to navigate the player's plane sprite accurately and can be a cause of major frustration.
The problem was that my code was too fast for the CoCo's sound multiplexor switch ($FF01 and $FF03) which I was using to switch between the joystick's X and Y axis. John said that a substantial delay was needed to allow the switch to complete the switch else data was going to be erroneous. I followed his advice and my joystick routine worked a charm.
With these challenges out of the way, I was able to complete the plane sprite routine. I have added the screen flight boundaries, a spinning propeller effect and the pilot's eyes now animate up and down in relation to the planes verticle movement.
Popstar Pilot... The Video!
The demo video shows the current test version of my code. I have created a short scrolling terrain field and provided the ability to manually switch the background raster bars as I play starting with the Blue Skys background, then the Rainbow Caverns, followed by the Wild Storm and ending with the futuristic Tech World (parallax effect coming soon). These will make more sense once the levels are properly defined.
The best news of all is the speed of my final routines. When I look back at my original vector based scrolling routine, which I thought were fast, and compare my speed readings as I explained in Chapter 9, the current tile based routine with the plane sprite section takes up only slightly more time. A great achievement and this gives me hope that I will achieve my 30 frames-per-second target.
But I remain cautiously optimistic knowing that there is still a way to go.
Copyright 2013 by Nickolas Marentes