OCTOBER 2018

Chapter 08 - The Graphics Engine (Part 2)


Back in Chapter 2, I described my idea for implementing the Graphics Engine for GunStar, based on the engine I created for my old game Escape Zone for the TRS-80 Model 1 back in 1984.

In this chapter, I have taken that engine and refined it for the CoCo3 and the Hitachi 6309 processor. The 6309 improves on the speed of the standard 6809 by running many of the opcodes faster (at the same clock speed) and adds several extra registers and instructions.

Most importantly, it adds a memory transfer instruction called TFM which is a fast way of moving a block of memory from one location to another. Essentially a poor man's blitter and very similar to the LDIR command of the Z-80 processor except that TFR also supports interrupt operations during the copy process. 

This instruction alone is what makes this Graphics Engine possible and is faster and more memory and register efficient than the Stack Blasting technique used with a standard 6809 for fast memory copies.

Read more about the 6309 here:  https://en.wikipedia.org/wiki/Hitachi_6309

The 6309 is the best 8-bit CPU of that era and the ideal way to get an easy CPU boost on a CoCo. Software written to support the 6309 can generally see a 30% performance improvement and is generally compatible with the 6809 in its default 6809 emulation mode at power up.

Unfortunately it does require the removal of the CoCo3's 6809 processor which Tandy had soldered into the machine in order to save a few cents.

What a crime!

Fortunately there are a few people in the CoCo community with the skills to do a professional job of desoldering and removing the 6809 by replacing it with a socket to install a 6309. Many have already done so in order to run software such as NitrOS-9 and I felt that there was now a large enough number of upgraded CoCo3's to warrant switching my game development of GunStar to be 6309 exclusive.


Let the Mind Screwing begin!

The engine utilizes the 6309's fast memory transfer command to create a series of logical layers representing each frame of screen animation very similar to the Cel Animation technique used in old cartoons.

The graphics logically comprise a background and two overlay planes. I can therefore boast that GunStar will have three layer graphics!   :)

1. The Background plane keeps a scrolling backdrop.
2. The Sprites plane allows moving objects to be drawn over this background.
3. A third Overlay plane is then used to display score and other information superimposed on top of the other two planes.


The Background

Because I have yet to create the graphics tiles for the terrain, I will utilizing dummy graphics to help in the explanation.

Two areas of memory are used as a storage area for the Background planes. These are not displayable video planes, just an area of RAM allocated as graphic buffers representing 192x225 pixel (96x225 byte) 21K screens.


There are two stages to creating the background, each utilizing the 6309 fast memory transfer command.


Buffer 1: Graphics are drawn linearly a scanline at a time. Each new scanline is drawn above the last scanline. After the very top scanline is drawn, the process loops and continues back at the bottom, overwriting the old scanlines.

Buffer 2: Buffer 1 is then copied to Buffer 2
and in the process corrects the scanline ordering so that the older scanlines are below with the newer scanlines appearing above it.

The area from Buffer 1 where the new scanline was drawn and below is copied to the top of Buffer 2.

The area from Buffer 1 above the newly drawn scanline is copied to Buffer 2 below the previous area copied.
 

This process repeats endlessly giving the effect (in Buffer 2) that the older scanlines are scrolling downwards and off the bottom with new scanlines appearing at the top.

Why don't I just do a single memory copy to move the graphics down and draw the new scanline at the top each time?

I need to have two background buffers for reasons that will become apparent as we progress.


It's not efficient to do a whole buffer copy on Buffer 1 to achieve the scroll then another whole buffer copy to create Buffer 2.

BUFFER 1                                                                               BUFFER 2
  



BUFFER 1                                                                               BUFFER 2

  



BUFFER 1                                                                               BUFFER 2

  


The Sprite Plane

Now that we have the Background plane (Buffer 2), I can place all the Sprites (moving objects) onto this plane using a method best suited to the job depending on how well I need it to be overlaid.

I could merge the pixels of each sprite using a masking technique or just write the sprites without pixel masking which would be faster but may leave black outlines on parts of the sprite. I could store the sprites in memory and copy them to the Background plane or use the faster Compiled Sprites technique.


Ultimately, I will be using compiled sprites for speed but may use a more conventional sprite techniques depending on the complexity and animation characteristics of each Sprite.

Collision detection is another area I need to consider but this will come later in development.


Clipping

These Background buffers are mapped in memory representing two virtual 192x225 pixel displays. The CoCo3 doesn't produce a display mode such as this. In order to display the game graphics using a graphic mode that the CoCo3's GIME chip can output, I need to clip the excess parts of the Background buffer so that it fits into a chosen resolution.

I have chosen a display resolution of 128x225 pixels with 16 colors so I therefore need to remove a 16 pixel width area on either side.

Why have I created this wide Background buffer?


To allow objects to appear to move in and out of the field of view cleanly without the need to waste CPU time working out the off-screen parts.  
(Refer to the image on the right)

Another feature that this clipping provides is the ability to move the displayed area left and right within the larger buffer space providing panning of the display during the game within a larger area of space.


Double Buffering

In clipping the image to the display size, I merely copy the required area to another area of memory. This opens the door to double buffering of the display output.

I allocate two areas of memory to hold the clipped image and by cycling the display between each area, I can create a nice flicker free display.

While I am displaying the previous game frame from one area of memory, all this display processing I have covered is happening on the other area of memory unseen by the game player. When it is complete, the two display areas reverse roles and the newly created frame is displayed and the other area is erased and the next frame built.




Overlay Plane

With all the Sprites placed, the last thing we need is the Score and other Status displays.

This plane has a higher priority than anything on the Background or Sprite planes and any graphics here will be overlaid over everything else.

The final results are a very arcade'like screen with moving objects and overlays.



But wait! There's more!

Normally this would be the stage where we need to switch the display buffer roles to prepare for the next frame by undoing everything we've done and restoring the background to its original state so that we can place all sprites in their new positions for the next frame.

But this is where this engine shines. Because there are two background planes, one of which gets the new terrain drawn and then copied to the second background plane, it will therefore automatically erase all sprites and restore the background to the next scrolled position. No need to do anything!

This is where this engine makes up for the time it takes in all the copying of memory and makes it far easier for the programmer to manage.


It's a wrap!

I now have the code running and scrolling the background. Currently, it is scrolling random data in RAM until I insert the routine to draw the background tilemap. It is running smoothly and jitter free while running the two channel interrupt driven sound effects I created in chapter 3.

Feature summary so far...
  • Double buffered video output
  • 1 byte vertical and horizontal scrolling
  • Wider virtual bitmap
  • 3 logical graphic planes
  • 2 channel real-time sound effects
  • Sprite simplification

Next on the menu is the tilemap editor and generator so we can see some actual terrain moving. I'll try have a video to show in the next chapter.




Copyright 2017 by Nickolas Marentes