[comp.sys.amiga.programmer] Lemmings - a tutorial Part II

farren@well.sf.ca.us (Mike Farren) (03/24/91)

NOTICE - this entire posting is Copyright (c) 1991 by Michael J.
Farren.  The only reproduction rights granted under this copyright are
for electronic transmission between Usenet sites, and other sites
connected to Usenet sites.  Contact farren@well.sf.ca.us for reproduction
rights other than the above.

Level 1 - THANKS FOR THE MEMORIES

One of the most frequent justifications one hears from Amiga game
developers trying to explain why they have taken over all of the
system, totally locking out any other use of the system and requiring
reboots to start their game and to get out of it, is that they need
all that memory - they cannot spare even the small amount taken up by
the system.  I'd like to look at that a little more closely, with
Lemmings as the exemplar.

First, let's figure out just how much memory we have to deal with.
Remember, we're talking about a 512K unexpanded Amiga 500, so we start
with exactly that - 512K.

Now, we have to subtract the amount of memory the system uses.  A
complex startup-sequence, one which does a lot of AddBuffers, assigns,
residents, and like that, can take up a lot of space.  But that isn't
really needed for a game; you can presume that those who want fancier
systems probably have (or should have) the extra memory and hard
drives to support them.  For the base A500 crowd with only one floppy,
a stripped-down startup-sequence is all you need.  Such a startup
takes about 115K right off the top, once the system is loaded and
going.  Once you start your application, though, you can CloseWB(),
and immediately get 32K of that space back when the system frees the
Workbench screen memory.  So, we're talking about available memory in
the range of 512K less approximately 80K.  Let's call it 82K for the
sake of keeping things even, and say that we've got 430K left to use.

The first consideration is screen memory.  Lemmings, as far as I can
tell, requires four areas of memory, arranged as three ViewPorts and
one BitMap.  First, and largest, is the area used to hold the
background image - the playing field for each level.  My best estimate
shows this area to be approximately 160-165 lines high by five screens
(320 pixels) wide, in sixteen color lores mode.  So, this area will
use (165 lines X 40 bytes X 5 screenwidths X 4 planes), or 132K.  Not
a small number, but let's finish this up before we talk about that.

Next, there are two ViewPorts used to double-buffer the actual
display, what you see on the screen.  For a while, I thought that the
way they did this double-buffering was to have two complete copies of
the entire background, but after a bit of thought, I realized that
what was probably happening was much simpler.  I'll discuss just how
the code works in the next installment, but for now, suffice it to say
that there are two buffers.  During each cycle, the non-visible buffer
is cleared, the animated objects drawn in, the background is copied
in, and all of the lemmings which will be visible once the buffer is
shown are drawn.  Finally, the buffers are switched - the one that was
visible is no longer visible, and will be drawn into the next cycle
around, while the one you just drew to is shown on the screen.

At any rate, you've got two buffers.  Each of them is a couple of
bytes wider than a full screen (to allow for scrolling), and the same
height as the background (165 or so bytes).  So, they will use (165
lines X 44 bytes X 4 planes), or 29K each.  Let's call it 60K for both
of them.  We're now up to 192K used.

Finally, there is another ViewPort used to hold the icon display on
the bottom (along with the score line and map).  This doesn't really
need to be double-buffered, as not much action ever takes place in it,
so we won't.  One buffer, about 40 lines high and 40 bytes (one
screen) wide, equals (40 lines X 40 bytes X 4 planes), or 6.5K.  Our
grand total for screen memory is, therefore, 199K.  Let's call it
200K, just for the sake of those round numbers, so we can now say that
there is 230K left for the actual game data and code.

From that 230K, we must subtract the storage needed for data lists and
animation images, and the like.  I figure that each animated object is
going to take about 4K, and there don't seem to be more than about
five unique objects on any given level, so that amounts to 20K more.
Add in the images for the ten different types of lemming (walkers,
fallers, climbers, floaters, blockers, builders, bashers, miners,
diggers, and the "jumpers" you get when they hit the exit), at about
4K each, and you're up to 60K.  Add another 10K for general slop, 10K
for data lists (such as the structures for each lemming's position,
status in the animation cycle, and such), 40K for sound data, and 30K
for such things as the "You really blew that level" display, fonts,
and such, and you're now down to 80K for code itself. (And don't
forget - all of my estimates are rounded up - the actual memory usage
is probably somewhat lower, so you'll have even more memory in "real
life")

80K doesn't seem like much, but in the next episode, I'll talk about
just what you can do in 80K, and what you need to do if you want to
write your own version of Lemmings.