|
24-Apr-07 |
Atari
XL/XE Space Harrier Conversion Project
| Latest | Mar-07 | Aug-06
| May-05 | Feb-05 | Oct-04
| Aug-04 |
| Dec-03 | Mar-03 | Jan-03
| Dec-02 | Jun-02 | Apr-02
|
5th February 2005
Plenty of diversions (and my usual slow pace of work), hasn't seen
much visible progress to report on the game.
Cartridge Formats
I finally got around to looking at the pros and cons of different cartridge
bank switching methods that I could use for the game.
There are 3 existing cartridge designs that cope with the amount of
memory I expect to use with Space Harrier. Only MegaCart, XEGS and AtariMax
MaxFlash allow for 8Mbit cartridge sizes. They are also sufficiently
different that substantial changes have to be made to a program if you
decide to swap from using one to another - which is what I've been doing.
I had been using the MegaCart format as it seemed to be the only one
that offered the potential for more than 8Mbit of memory, which I thought
initially I would need.
- 8Mbit MegaCart is organized as 64 banks of 16K. Only one bank of
memory is available at any one time. (The Atari hardware is designed
to map cartridges into two 8K memory areas only). Switching to another
bank is achieved by writing the bank number required anywhere in $d500
to $d5ff
- 8Mbit AtariMax MaxFlash has 128 banks of 8K banks, again with only
one bank available at a time. Switching banks is done by writing anything
to $d500 for bank 0, $d501 for bank 1, $d502 for bank 2. etc.
- 8Mbit XEGS is organized as 128 banks of 8K, and is more flexible
with banks. The last bank in the cartridge is always mapped to one
of the 8K memory areas, whereas the other 8K area is for using the
different 8K banks as needed. Writing the bank number
required anywhere in $d500 to $d5ff switches the bank.
The bank flexibility is why I'm using the XEGS format now.
It means for example, that the full cartridge size can be used, rather
than having to dedicate a small amount of space in each bank for dealing
with silly little things like someone deciding to press the reset key.
I may revisit the AtariMax MaxFlash though as it is the only cartridge
which is re-writable by the owner themselves - an ideal way to distribute
games over the Internet for use on real Atari hardware. However good
it may be, the trouble is it's a recent development, and is not widely
supported under emulation. Steven Tucker (of APE fame) has done an excellent
job with it though, and I hope it will gain in popularity. Many games
that required multiple disk swaps have been converted to use this cartridge.
It is even possible to store high scores and game settings on it (although
there's no example code on how to do that, yet). More details on MaxFlash
and APE at www.atarimax.com
Display Mode Experiments
Richard Phipps of Reflected
Games dropped me an e-mail a little while back, offering some great
words of encouragement. Although he's now programming some lovely shareware
games for PC, he still remembers a lot of technical details about the
Atari 8-bit. We exchanged some ideas about getting more colours on screen,
and he even whipped up some simulated screenshots for me (see below).
These ideas involved mixing GTIA modes (9 or 16 colour, but low resolution)
with higher resolution (but limited colour) modes on alternate scan
lines, and then interlacing the screen to make the scan lines merge.
Unlike the best modes for displaying lots of colour on the Atari, some
of these modes can be done without having to use Display List Interrupts
on every scan line or tying the processor to a display kernel routine,
which both leave few CPU cycles to do anything else. The lack of colour
resolution on these modes can make for some strange artifacting around
colour boundaries, and overlaps of moving objects can look a bit messy
(reminiscent of the infamous Sinclair Spectrum colour clash), so chances
are I'm not going to use these modes. There doesn't seem to be anything
new under the sun though - I recently saw CIN pictures for the first
time, and it looks as though they work pretty much the same way!


By the way, be sure to check out Richard's excellent original
retro styled PC shoot'em up game, called Storm. It reminds me somewhat
of Thrust or Oids in visual style, although most of the gameplay elements
are different. A free demo or the full Shareware version can be downloaded
from www.reflectedgames.com
I know some people don't like using interlacing methods
to get more colours, because of the flickering produced. However, I
was reminded of why I went down this route when I looked back at my
oldest, 4 colour version of the game started in the late eighties. Black,
Green, Grey and a changing background colour were to be used throughout
the game; I think it would have ended up looking very dull indeed.


Backgrounds and Run Length Encoding
There's a neat trick the original arcade machine uses
on the background parallax layers. Several layers just have a different
colour palette applied to them and get reused on many stages. Now that
I'm doing parallax layers too, I can also use the same trick to save
memory.
Looking into how best to store the background parallax
layers and stage data, took me on an interesting detour into different
implementations of Run Length Encoding. Experts look away, as what follows
is an "Idiot's Guide" to Run Length Encoding, and I will be
your idiot for today.
Run Length Encoding (or just RLE) is a kind of poor man's
compression which is easy to implement and quick to run, even on old
8-bit computers. Even the concept is simple and obvious, unlike most
other (admittedly much better) compression algorithms. The concept is
just this - when you get several repeating items of the same value (a
run), just store a count of how many there are, along with the value
of the repeating item.
4,4,4,4,4,4,5,5,5 becomes 6,4, 3,5
This saves space when we have nothing but repeats, but
what happens when values do not repeat? In the easiest approach we might
store a count of just 1 for those items that do not repeat.
1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 1,1, 1,2, 1,3, 6,4,
2,5, 1,6, 1,7
As you can see, in this case it has the unfortunate effect
of expanding the data, rather than compressing it. This is where things
get slightly more interesting. There are a few different approaches
to that problem, and which one gets the best result is dependent on
the kind of data you will be encoding.
Approach number 1. Use two repeats of the same
value to show that a run is required, and the value after is the count
remaining. This is pretty cunning, but not always that efficient. Note
how in the example the two 5's below actually expand in size. Runs of
3 take up the same size, but any bigger runs will start to benefit.
The non-repeating data takes up the same amount of space.
1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 1,2,3, 4,4,4, 5,5,0,
6,7
Approach number 2. Use an unambiguous symbol to
represent that a run is required. In our examples we are just using
numbers, so we could use anything other than a number for a symbol.
Below the character "C" is chosen as a symbol. This approach
has the advantage of not having to expand the data when it is not worth
it; we can leave the 2 fives as just 2 fives.
1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 1,2,3, C,4,6, 5,5,6,7
What if there is no suitable value for a symbol though?
If we want to have "C" as part of the data in the above example
we hit a problem. One answer is again to use a repeating value to indicate
that the symbol is to be used as real data, rather than just a symbol
- but any runs of the symbol cannot then be represented as a count.
Alternately we could represent the occurrence of the symbol as a run
with a count of just 1 item. It is therefore important that a rarely
used value is chosen as the symbol, or the data will start to expand
every time the symbol is required to be represented in the data. If
the symbol is not always going to be the same then we must also record
the symbol value in the data. Right at the beginning is an obvious place
to put it.
1,2,3,4,4,4,4,4,4,5,5,C,6,7 becomes C, 1,2,3, C,4,6, 5,5,
C,C, 6,7 (symbol as a repeat)
or 1,2,3,4,4,4,4,4,4,5,5,C,6,7 becomes C, 1,2,3, C,4,6,
5,5, C,C,1, 6,7 (symbol as a count)
Approach number 3. This one actually has a name
- it's sometimes referred to as "PackBits". The basic idea
is to have a count for the runs and also a count of how many non-repeating
values there are before the next run. We do need to distinguish between
the two kinds of count though, and this reduces the range of the count.
The usual method is to represent one of the counts as a positive number,
and the other as a negative number. In the example here we use a negative
value to show when the count is for a run.
1,2,3,4,4,4,4,4,4,5,5,6,7 becomes 3,1,2,3, -6,4, -2,5,
2,6,7
That's pretty much the basics for Run Length Encoding.
One thing that hasn't been mentioned yet, is how to know when we've
got to the end of the data. You could have the file length stored at
the beginning of the data, and keep count of when to stop. A normally
more efficient way (at least on old processors with few registers, like
the 6502) is to have a zero in the count value to represent we've finished.
The Real Thing (in our House)
A couple of weeks ago, proof came that my brother is,
unbelievably, an even bigger Space Harrier nut than me - he won a full
motion deluxe version of the original arcade machine on eBay (and it
is supposed to fit in the back room of our small 3 bedroom semi-detached
house). Below is a picture after the machine had to be totally dismantled
just to get all 300Kg of it through the door. I won't even go into detail
about the ferry trip to France, and the 480 mile round trip with a 3
1/2 Tonne tail lift lorry to collect it. As you can see from the picture,
it now joins a smaller version of Space Harrier and a JAMMA cabinet.
It is in working order, but there is quite a bit of restoration required;
all part of the fun!

Top