Chapter 02 - The
Once I get past
the idea stage, I then start the process of
breaking the development stage
smaller tasks to get a clearer picture of the overall job ahead. I'll
isolate which core functions will be needed by the game and these are
usually the most CPU intensive parts of the game that
simply must work efficiently,
reliably and as quick as I can make them.
These functions tend to always be:
this chapter I will talk about the Graphics Engine and what I have
developed so far.
- The Graphics Engine
- The Sound Engine
new from something old
For Gunstar, I will be going "old school" and resurrecting a Graphics Engine I used a long time ago.
I mentioned in the last chapter that back in 1984 when I was still a
young high school lad, I created my last TRS-80 Model 1 game called Escape Zone. This was my last game before moving on to the CoCo. This game was a
classic vertical scrolling shoot-em-up.
This game featured a Graphics Engine that provided software sprites and
overlay functions that were advanced for the time, especially for the
TRS-80 Model 1 with its low resolution monochrome graphics. This game
featured impressive sound for a computer with no real sound hardware.
All sound was generated by toggling the cassette output for the
generation of 1-bit sound and there were no interrupts or
fancy hardware to utilize.
But the Graphics Engine that I used in this game had some interesting
capabilities that if converted to the CoCo could provide a slightly different way of managing sprites and overlays. Click on
the screen below to open a YouTube link that shows Escape Zone in action.
|"You have been held captive by the evil Dakors since
they first captured your craft during a daring space raid. But the
Dakors made a mistake of treating you just as any other human captive
and so you manage to escape from confinement and have reached your
escape craft. The Dakors are alerted to your escape and now there is no
time to lose!
Prepare to thrust your way out of the Dakors' command destroyer and
into open space via a tight winding tunnel filled with deadly "Blipop"
and "Bizzo" mines. Once in space, destroy the super-fast "Flipps",
maneuver through the dangerous meteor shower and dodge your way past
the "Reverso" crafts and "Putt-putt" missile ships into the safety of
1984 STORY PRETEXT
How the Graphics
Engine worked for Escape Zone
My thinking for this Graphics
Engine was based on the idea
of creating separate graphic layers... a background layer, a sprite
layer and an overlay layer.
The background layer was an actual bitmapped layer but the sprite and
overlay layers were just drawn over onto this background layer that logically represented separate layers.
I also incorporated double buffering to hide the user from the actual
game screen setup mechanics to eliminate screen redrawing and
I allocated an area of RAM the same size as the actual
video display. On the TRS-80 Model 1, that meant reserving 1024 bytes
and this is where I drew all of the background graphics. Then I drew the
sprites onto this same background layer.
the sprites were drawn and collisions processed, I could then draw
extra graphics such as explosions and things like the superimposed "Escape Zone" text
shown in the YouTube video, being overlaid on top of the game demo as it was
playing. The size of the sprites and overlays could be large dependant on how fast I wanted the game to be.
This was the completion of one frame and was then a matter of
copying the entire 1024 bytes onto the actual
1024 bytes video display
RAM. The user did not see any of the individual graphics being drawn,
only the completed frame after it was copied to the display using the
fastest possible way I could find. The area reserved in memory used to
create the initial frame
was then erased
and the entire process restarted for the next frame to
be displayed. This erasure was very important and I
will explain why a little further down.
This system worked very well for the TRS-80 Model 1 since it couldn't
reposition the display in a different area of RAM and copying the 1024
bytes of RAM was within the processing speed of the 1.774 Mhz Z-80 CPU.
Conversion to the CoCo... BIG FAIL!
When I moved across to the CoCo1 in late 1984, I tried to carry this
Graphics Engine across using the new color and higher resolution
graphic modes that the CoCo1 provided but problems surfaced almost
TRS-80 Model 1 used 1024 bytes for a
video display but the CoCo1 high resolution graphics modes used 6144
bytes. But this problem could be offset by the CoCo's ability to
reposition the video display anywhere in memory. There was now no need
to copy the finished plane to the video display RAM anymore. I could
simply keep 2 screens in memory and alternate between the two keeping a
doubled buffered system for cleaner output.
But there was still the need to erase a page and this meant clearing
6144 bytes. That was 6 times more RAM than the TRS-80 Model 1. To make
matters worst, the CoCo1 was running at a slower processor speed of
0.89 Mhz compared to
the 1.774 Mhz of the TRS-80 Model 1.
The Z-80 also had a brilliant command called LDIR (Load Increment
Repeat) which allowed a fast block copy of RAM with a single
instruction once the source and target locations were defined. The 6809 didn't have that. LDIR was the one command on the
Z-80 I sorely missed.
To be fair, there were lower resolution video modes that used less
that I could have used but this was my first venture into high
resolution color graphics and I wanted to move away from the low resolution graphics I was so use to. I also could
have used a smaller area of the screen rather than the entire screen
but I was fixated at doing the whole screen. :)
Graphics Engine was very CPU intensive and my 6809 programming skills
were still in their infancy, so I abandoning it and looked for a
different method of handling the high resolution graphics.
I wasn't a Jedi yet! :)
The benefits of this
Graphics Engine was that it eliminated the need to keep track of the
background that got
overwritten by sprites and overlays. This also simplified the graphics
routines used to process the sprites and overlays and therefore offset
some of the CPU cycles lost during copying and erasure operations. The graphics were also clean and flicker free due to the double
the years that followed, I used more common methods for sprite
creation basing them on the requirements of each game. It wasn't until
1992 when the desire to create a vertical shoot-em-up
again resurfaced. This is when I began developing Cosmic Ambush
This incomplete game was my first attempt at using the hardware
features of the GIME chip to create a seemingly endless hardware
vertical scrolling background. It was a reasonable attempt at a
vertical shoot-em-up but I wanted more from it.
There was some flicker
of the sprite animations and the score overlay had to be constantly
redrawn otherwise it too would scroll off the screen. I didn't use
double buffering for this game since a screen occupied almost 32K and I
was planning this game to be on a ROM cartridge that only required 128K
the image on the right to
see Stevie Strowbridge's video review of Cosmic Ambush.
Using features such as the hardware scrolling comes with it's own
tricks and traits. What you could
do, was dictated by the hardware's capabilities. For example, the
hardware vertical (and horizontal) scroll moved the entire screen. I can't set an area
of the screen that would remain static as the rest scrolled
vertically by. In Pop*Star Pilot, I tricked the hardware to create split screen scrolling but that technique only works
in the horizontal direction.
For Gunstar, I need vertical scrolling with many sprites and overlays. This poses a challenge and for this I have
summoned my 32 year old Graphics Engine. In reality, with 512K RAM, I could have expanded on the Cosmic Ambush
Graphics Engine and made it work but I had other ideas of what I wanted
to do which would have complicated things... besides, this was
going to be more fun. :)
The legend returns!
Before I was to officially start this project, I needed to prove IF
it could be done at the desired speed. I was aware of the problems I
had encountered with the original and set about to do some trials to
evaluate the challenges ahead. This time, the
challenges were even greater.
My favorite and preferred video mode was 320x225x16 colors. This is a 36K screen and
I strongly suspected that I would be trying to take the bull by the
horns with this one but I had to start somewhere and I chose to start from the top
and work my way down.
Firstly, I needed to create the endless vertical scrolling
background and here I use the same system as I had used in Cosmic Ambush where I allocate an
area of RAM for the Background
Layer that was two display screens high. I would position my display screen in
the bottom half of the background layer and for each frame in the game,
draw the next incoming line just off the top of the displayed screen.
With the new line in place, I move the video display screen up one line
to bring the new line into view then copy the newly displayed line
from the top of the screen to just off the bottom of the screen.
This process looped and the page would scroll line by line until the
new graphics were displayed in the top half of the background layer. This therefore also created a copy of the top half into the bottom
half as it scrolled upwards. Now,
all I had to do once I had reached the top of the background layer was to
reposition the displayed video page to the bottom half again and start
over, continueing the layering of the new background graphics. This
could go on forever as long as I had graphics to put up.
So far so good. Now for the sprite and overlay layers.
At this point, conventional sprite routines would draw the desired
sprites directly onto this background layer. They would firstly store
the area below each sprite into another area of memory, merge the
sprite graphics with the background in whatever way preferred
(byte, pixel etc) and when the completed frame was finished and
displayed, restore each of the sprite backgrounds back to their
original state, repeating the process for the next frame.
Double buffering usually required two sets of sprite backgrounds
to be stored and then restored. The more sprites and overlays, the more
background that was stored. Depending on the sprite routines, this
could also have meant that the same background area was stored twice in
the case when two (or more) sprites were overlapping. This whole
business of maintaining the background with double buffering could become complicated and
presented some repetition unless you wrote a smart and complex sprite routine to
manage it all properly and efficiently.
I'm getting too old for this sort of thing and needed an easier approach. :)
more flexible and manageable system
re-implementing the old Graphics Engine from Escape Zone,
I’ve come up with the following…
well as the background layer as described above, I
allocated two areas of memory as Display Layer 1 and Display Layer 2 .
be the areas of RAM where each of the double buffered screens reside.
double buffering will work by displaying one of the
display layers (I call this the active screen) while the
redrawn out of view. Once completed, it becomes the new active
and the other gets redrawn. This cycle continues for the entire game.
and overlays are drawn during this redrawing
process. The part of the background layer that is to be displayed gets
copied first to
this non-active display layer. Here, we need the absolute fastest copy
to copy the background. This process automatically erases all previous
and overlays leaving a clean, updated and scrolled background ready for
next frame. All sprites are updated, drawn, collisions checked and
before finishing off by drawing all
(explosions, score readouts etc.) over everything to finalize the frame
is then made active and displayed to the user as a fully completed
process cycles over and over.
This simple idea fulfills my desire for a simple, flexible and manageable graphics
engine with sprite overlay... at least in theory.
Now to get some real
code running to see if it will actually work.
My biggest concern was whether I could create a fast enough copy
routine to transfer a screen worth of memory from the background layer
across to the designated display layer. I was essentially trying to create a fast software Blitter memory copy mimicking
what the Commodore Amiga had within it's custom hardware. (Of course,
the Amiga had real sprites and multiple overlaid bitmaps as well, but
on the CoCo we have to program all this)
I'll save you the suspense.... no I couldn't. :)
But I suspected that. A 36K display screen was just way too much to copy in
a fast enough time frame with the CoCo3's 1.79Mhz CPU.
The CoCo3's video is composed of 60
interlaced fields per second. Two fields combine to make a frame.
Therefore, the screen runs at a maximum of 30 frames per second. Video
data from the CoCo occurs on one of those fields. The other field is
blank and this is why we get the black scanlines between live
scanlines. If both were live, the CoCo would be producing 450
interlaced lines per screen. It can't and so produces half this number
(225) with the other interlaced half as black scanlines in between.
It was clear I had to run a lower resolution so that the 6809 could
copy it within one field. This left me another field to create sprites
and process the remainder of the game if I wanted to achieve that magic
30 frames per second speed. This was still a tall ask and it was more
realistic that I aim for half that at 15 frames per second... but I'll try. I would not
accept anything lower than 15.
I experimented with several resolutions and utilized Stack Blasting to
obtain the fastest speed I could muster. This is when I began exploring
the 6309 opcodes and I came across a great revelation!
The TFM (Transfer Memory) command! This was the 6309 equivalent of the
Z-80 LDIR (Load Increment Repeat) command which I missed so much from
my TRS-80 Model 1 days. The TFM command was actually better than the
LDIR because it could work with an interrupt service routine and
continue to do the memory transfer. Brilliant and perfect for my needs!
I spent a lot of time and tried many methods of transferring data using
stack blasting with the 6809 but the 6309 in native mode and the use of
TFM would beat it every time. In the end, I made some compromises that
brought me close to the 6309 copy speed. Gunstar will implement both
and choose the appropriate one dependent on what CPU you are
In the end, I found I could use a 128 x 112 pixel x 16 color mode. This
is the same mode I used in my game Gate
except with a slightly higher vertical resolution.
The image on the right is a screen capture of the game screen from the VCC emulator with the
copy routine running but no graphics to scroll. VCC fills the RAM with alternating 0 and 255 bytes on
bootup causing the byte wide (2 pixel each) striped bars. A real CoCo3 fills it with random data.
display is the same width as the standard 32 column VDG text screen but
taller due to the extended vertical resolution. This is fine since most
arcade vertical shoot-em-ups actually use a
vertically oriented display anyway. I'm happy to use this display
mode for Gunstar.
I drew up some test graphics
(the player's spaceship that will be used later in the game) and I liked it. It
obviously wasn't as sharp as a 320 x 225 mode but the larger spaceship
size had a charm of it's own. I liked it and that will end up being the
design used in this game.
I even based the spaceship artwork that you can see
at the top of this blog page on it. :)
had an acceptable resolution and my copy process was achieved in just under one
field for the 6809 version and a bit less on the 6309. The 6309 version
will also have horizontal panning. The actual background will be
wider than what is displayed and will shift left or right
proportionately with your spaceship as it travels vertically. The 6809
version can't quite muster the speed needed to perform this in the same way so it will stick with just
This makes a good reason to upgrade to a 6309 and I hope to add
other features that will specifically utilize the 6309 if found. I love the
The lower resolution of the graphics will hopefully be
offset by the amount of detail in the overall animations. If I were to
design a game where I wasn't trying to copy an entire screen, a higher
resolution may have worked but I have a plan for what I am wanting to
achieve which hopefully will become clearer as we progress through the chapters of this blog.
That's the end of this blog chapter. I hope I've made sense and not confused everyone.
I must stress that this is not the best Graphics Engine for all games but it's a great Graphics Engine suited to this kind of game and for what I am trying to achieve.
In the next chapter, I will add in the second most time consuming
component of the game... the interrupt driven sound.
I need to pull off the Graphics Engine and Interrupt Driven Sound
together at a fast enough rate. Fun times ahead!