As I previously posted, one of the Arcadia programmers (Grand
Slam Tennis) wrote to me looking for a way to play his game. Well,
we're getting closer to that goal - I've successfully emulated Grand Slam Tennis
with the MESS emulator. The MESS emulator is arguably the only emulator
left in existence for the Arcadia 2001. The 2001 emulator (Arcadia's
"dedicated" emulator) only runs in DOS (won't run in Windows NT, 2000,
or XP), and it won't run the Grand Slam Tennis game. Here's the story of
how Grand Slam Tennis was made in the words of its creator, Tom Pittman.
|

|
|
Grand Slam Tennis, emulated with MESS.
The screen only shows one player at a time (rapidly switching between
players). |
Where to start... A business acquaintance told me about his uncle who
ran some kind of video game company in Hong Kong and was looking for game
programmers, and I was interested. It was kind of strange, because I don't play
video games, but I had written a few TinyBasic (text-based) games for that
market. So I went down to the local video game arcade; I never spent a nickel
there, I just watched people play so I could get a feel for how they play.
Anyway, my friend brought over the development hardware and a big Sony TV to
play it on (I don't watch TV either ;-) and a competitor's tennis game (I think
it might have been Coleco, but I cannot remember). I played with it some and
decided it was a bit hokey. The vendor wanted something "3-D" with a
shadow to follow the ball around. I guessed I could do that.
Problem #1: I don't play games, not even live games like tennis. I
knew nothing about the game. So I went to the library or a bookstore (I can't
remember which) and got a book on tennis rules. The scoring is bizarre --
certainly far more complex than the simple +1 scoring of the competition -- but
not too complicated to program the computer to do it.
Problem #2: In the competitor's product (and in most video
games, many even today 22 years later) the characters sort of slide around on
the screen to follow the joystick, and their feet move, but their feet don't
stick to the ground. It's like they are skating on ice. I resolved that MY game
would be physically correct. In the competitor's game, the player just flipped
from racket on the left to racket onthe right, mirror image; that was the only
swinging action. Again, I thought that real tennis players had a little more
animation than that. So I went down to the local video rental store and rented a
VCR and a tape of Billy Jean King teaching tennis. There was some lecturing, but
mostly a lot of video action BJK serving the ball, or BJK running across the
court to catch a ball with her forehand, or running the other way to catch it
with her backhand, stuff like that. I set my 35mm camera up on a tripod in front
of the TV and paused the tape a lot and took a lot of stop-action sequence
snapshots off the screen -- maybe three or four rolls in all. Then I lined up
the snapshots in sequences all over the kitchen counter and picked out the most
representative running and swinging and serving sequences. Then I copied the
posture and motion of BJK's moves onto graph paper. Well, not exactly, which
brings me to ...
Problem #3: Hardware limitations. The game console was
eventually sold as Emerson Arcadia 2001, with a Signetics 2650 8-bit CPU and
some kind of video chip that had 8 colors on maybe 256x256 pixels -- the pixels
were not even square. And there were eight 8x8 single-color sprites. A sprite in
computer graphics is a small picture that you can separately program not only
what it looks like, but also where it will be displayed on the screen. That's
how you get the skating effect: you run through a short animation of the
character's legs running, and then independently you set the X/Y coordinates of
where to show the character, and swish! It slides right over. Even in
video hardware where you don't have hardware sprites, it's so much easier to
program sprites for animation and motion independently, that the game software
tools do sprites in software. 256x256 is not a lot of pixels, and 8 colors is
pretty limiting. The sprites were a challenge in themselves: 8 pixels tall is
too small for the players. I finally settled on one sprite for the legs, one for
the head and shoulders, and one for the tennis racket. Each on-screen player was
three sprites, leaving two for the ball and its shadow. Having only one of the 8
colors for a sprite was also a limitation, so I chose generic solid colors for
the players, and white for the rackets and ball (and black for the shadow).
Everything else, had to be programmed pixel by pixel. Worse than that, each
block of (I think it was 8 pixels square) could only have one foreground color,
and then a single background color for the whole screen. It was like the old
character graphics from the days of the character-generator TV typewriters. It
maybe had your choice of text-only at the bottom, or some kind of text over the
whole screen. Now that I look at some of the other screen shots, I see that
their character generator was one of those done by a computer programmer, with
slashes through the zeros so they are hard to read. I consider that stupid, and
you won't find any slashes through MY zeros (I'll use the letter "O"
first).
|

|
|
Animation in Grand Slam Tennis was fluid, accurate,
and fast. |
Problem #4: Sound. The video chip did sound by giving it a
frequency of tone, or else a white noise generator (or both, I think), plus a
few bits of volume control. When a real tennis racket hits the ball, you get a
smushy-sharp "plock" as the ball compresses and rebounds, plus a
little bit of a twang when the strings in the racket oscilate like a guitar
string (but much shorter, because the cross-weave damps it quickly). I played
around with the sound for a long time before I settled on a burst of white noise
overlaid with a rapidly decaying high-frequency tone, and then little bursts of
white noise at minimum audible volume for the footsetps. I considered more white
noise at varying levels to be applause at the end of the game, but I don't think
I ever did it. My program was already becoming too big. It had to fit in a 4K
ROM.
Problem #5: Animation. I did not want my characters skating over
the grass, so I spent a lot of time carefully lining up the backward motion of
the foot animation in the leg sprites to be synchronized with the forward motion
speed I was moving the sprites, all on graph paper. In this game you cannot just
zoom your player over to the other side of the court, you have to walk or run
him over. I think I allowed for two speeds, walk and run, with an appropriate
number of frames per pixel rate of motion -- and of course foot motions to
match. As in the video, walking pickes up one foot and sets it down before
picking up the other foot. The foot that's on the ground must be moving
backwards through its sprite at exactly the same speed the sprite is moving
forward. When running there is a part of the cycle where both feet are off the
ground, and the whole character is bouncing up and down with the leaps. That
means the torso sprite must track the vertical motion of the legs sprite. I
vaguely remember that the sprites weren't quite big enough to move them smoothly
when running, so I had to adjust the sprite progress backwards (or forwards, I
can't remember) one pixel in that part of the cycle to keep the foot animation
continuous. It was pretty complicated. I never tried any diagonal running
-- or maybe I tried and gave it quickly up as too hard -- but I did do both
side-to-side and front/back walking and running. The front/back motion was
somewhat simpler, and I maybe had a single animation for both walking and
running. I wanted the winning character to jump over the net at the end of the
set, but I was out of ROM space; they run around it. Because of the color
limitations, you cannot tell which leg is in front of the other in the
side-to-side walking and running. This made things a little simpler, because I
could reuse the same leg sequence for both the left foot passing the right and
the right foot passing the left, and in both directions. I think I did a pixel
reverse subroutine to flip the image over and save pixel space in ROM. However,
the racket was a different color, so (assuming the players are right-handed),
when the player runs left-to-right on the screen, the racket sprite is in front
of the person sprites, whereas when the player runs right-to-left the racket
goes behind and partially disappears from view. I cannot remember whether I did
this by switching sprites (I think there was a strict hardware-enforced z-order
on the sprites), or by knocking out some of the racket pixels in its sprite.
Notice that the running animations had matching arm swings synchronized with the
legs, the way real people run. I did, after all, have all those video shots of
BJK running to look at. And of course, the racket was in the player's
hand, so it had to track the arm motion. Also, as the hand came down in the
swing, the racket rotated on its own axis (and partially obscure, if running to
the left). I wished I could have scaled the distant player to be smaller
than the near one, but I simply did not have enough resolution to play with
--nor enough ROM space for the code to do it. None of these are problems today.
So the guy in back looks too big. Oh well.
Problems #6, and 7: Game physics. Today you can buy a whole book on
game physics, and there are frequent articles in the computer game programming
journals; 20 years ago the topic did not exist. I won't say mine was the first
game to consider the physics, but it's probably in the first ten. Getting the
parabolic curve in the trajectory of the ball in free-fall is not hard, it just
takes a couple adds, the first to add the current ball velocity to the vertical
position of the ball every frame, the second to add a constant negative
acceleration to the velocity. This had to be done double-precision (16-bit
integer), with the lower byte representing a fractional pixel to get smooth
motion. All motion was done in fractional pixels, in full 3 dimensions; it
required three 16-bit adds to each position vector, then dropping the integer
part of the sum into the sprite coordinates. Oh yes, because this was a
perspective view, I had to add half (?) the Y-axis position to the Z-axis to get
the screen vertical, and run the cahracter in the back at half the spedd of the
guy in front. Maybe I scaled them proportionally for the middle court, but I
can't remember. I know I thought about it. I also thought about wind resistance,
making the horizontal velocity of the ball slow down proportional to the square
of its speed, but I think I decided not to. ROM space. Much trickier was
getting the new trajectory of the ball correct after it's been hit by the tennis
racket. I spent a long time working out the math (trigonometry) based on the
racket angle and velocity, plus the incident ball velocity, to find a new
reflected velocity. I was quite surprised that all the trig functions cancelled
out leaving me with two multiplies and four adds. In a CPU without even a
hardware multiply, that was a major plus. The physics were perfect.
The game was unplayable.
|

|
|
I threw out all the math and physics. Well, not
ALL of it, I kept the trajectory physics, but I made the racket
effectively four feet wide. . . |
Think about it for a minute: real tennis players have
spent five and ten years -- essentially all their childhood and early adult
years swinging hard objects held in their hand at a flying round object, making
the connection, and learning how to control where that ball flies off to.
Even newbie tennis learners have had some experience with hand-arm-eye
coordination, and yet they take weeks to learn how to get that tennis ball over
the net and not out of the court. A video game, on the other hand, the
prospective customer (probably an adolescent boy) expects to walk into the
store, pick up the game paddle for the game on display, press the buttons and
move the joystick -- all operations radically different from swinging their arm
while holding a large wooden handle -- and score within 15 seconds, or they
won't buy the game. With my original physics, you could have learned the
coordination, but it would have taken weeks, just like learning how to hit a
real tennis ball. That's a non-starter in the game market. So I
threw out all the math and physics. Well, not ALL of it, I kept the
trajectory physics, but I made the racket effectively four feet wide
(about six pixels, as I recall), and reverse-calculated how hard and what angle
the swing had to be to hit the ball and get it over the net. So if you are
anywhere near the ball, and you push the button anywhere near the right time,
you got it over. You can still control how hard you hit it (don't try a lob from
right close to the net, it will go outside the opponent's court; a gentle hit
from the back line will similarly not clear the net), and I think I left a
little of the timing in (which controls the left/right angle, depending on
whether it's a backhand or forehand), but it's relatively easy not to miss.
Problem #8: ROM size. Did I say the program was getting too big? It
WAS too big, twice too big. It was supposed to fit in 4K, but when I put it all
together, it barely fit in 8K. The vendor was pretty nice about it, he accepted
it and even paid me twice the agreed price (which I didn't ask for -- but I
didn't refuse it either :-) He liked it so much, he even sent over a
couple of his own programmers for me to tutor in game programming. Maybe that
was part of the deal in paying me double. That was an experience in itself. One
of them barely spoke a broken English, and the other knew only his native
Chinese. I don't recall what-all I told them, nor how much they actually
understood, but they seemed pleased with the process, and treated me to a huge
Chinese dinner (ordered off-menu in Chinese at a local Chinese restaurant). OK,
so Funky Fish isn't the most exciting game in the Arcadia catalog, but it was
what the guy could handle (I can't remember what the other guy did). Whatever.
Maybe some day I'll write another video game. The bar is a lot higher today,
involving 5-10 programmers, plus graphic artists, sound people (composers, etc),
animation, way more than any one person can do. But it's a meritocracy: people
are honored for what they (can) do, not who they are. I can still write pretty
good code.
Tom Pittman
2003 October 9
Sort By:
No comments were found for this thread.