Are you ready? Are you sure? So you've learned a bit about the history of R.C. Grand Prix and the man behind its creation, but how exactly did one go about making an SMS game back in the day? What did it take? What does all that code mean? Well, my friends, you're about to get a crash course, heh, in Master System programming from Scott Marshall himself!

Let's first understand a bit about how things were done back then as Stan rants a bit. Today you clickity click away on a computer with a bunch of lame, pretty intuitive programs to dish out your junk, but back then things were quite different. Look back at the first picture of him I showed you, see that set of beast wires coming out of that small computer and that huge PCB (printed circuit board) sticking out of that Atari 7800? That should give you a clue. For the Master System, Scott was the first person at Imagineering to work on the console. They started at "cold steel," which means they had no software whatever to build on, except for the "initial ROM checksum and startup code." What are they? "The checksum is the totality of every byte or word in the ROM (read only memory in case you forgot). The first thing a Master System cartridge does is add up every word in the cartridge memory. If it matches what is expected, it continues and starts up the game. If it doesn't match, then the cartridge or connectors or something is defective and, even if the game plays at first, it may freeze or do something wrong. Better to refuse to play the cartridge than have angry players lose their game mid way through. Start up code is just any code that needs to run before the game starts or the first screen appears. It typically includes the checksum test and initializing the graphics or sound chip. Start up code could also mean the code that sets scores to zero at the start of the game, puts the character at the front door of the maze, sets his initial weapons, dollar amounts, etc."

As for the programming itself, it was done in "assembly language on a PC plugged into a SMS via a CPU emulator, kind of like that picture with the 7800. The CPU emulator is a hardware device that lets you remove the CPU from, say, a console and then you plug the emulator into the CPU socket. The emulator connects to your PC or MAC or whatever. It allows you to load programs into the console, write and read memory, run programs, start, stop and single step programs. The console thinks everything is normal." And what the hell is assembly language?

"Assembly language is one step up from machine language, just a numeric representation of codes to get programs to work. Every program runs on this basically, and by utilizing numbers you get these programs to function. Machine language is all ones and zeroes and gets a computer's central processing unit (CPU) to function, where, for example

10110010 00000011 1001001011101100


might mean "test to see if this is round #3." All computers use this language internally. I more often than not used hexadecimal notation, which is essentially the same code made easier for humans to read where the above would be written as:

$B2 $03 $92 $EC


It's just one level of abstraction above machine language essentially. Next above that is assembly language, in which I'd now express this as:

CMP 3 (CurrentRound) ;compare current round with #3


Assemblers have macro features (which specify how what you put into a program will be displayed from some other source, in this case through your Master System to the television) in which you define what a series of words mean. For music you could say:

PLAY_NOTE G3 TONE_GENERATOR_2 BEATS_3
PLAY_NOTE F3 TONE_GENERATOR_2 BEATS_5
PLAY_NOTE E_FLAT3 TONE_GENERATOR_2 BEATS_3
PLAY_NOTE D3 TONE_GENERATOR_2 BEATS_2
PLAY_NOTE D3 TONE_GENERATOR_2 BEATS_1
PLAY_NOTE E_FLATE3 TONE_GENERATOR_2 BEATS_2


The above codes in fact define the first 6 notes of the R.C. Grand Prix theme. I would then define what hex codes that would translate to, and write a program that reads the binary data (the number codes mentioned before) and loads the sound generators and keeps track of the timers to create music (a sequencer, in musical terms). A similar sequencer handles sound effects, following instructions to load numbers into the sound registers and control the pitch, and volume over time."

Thus, Scott would begin by getting the system to make a sound, "the easiest way to prove a program is running, then get it to change the background color of the screen and it's onward from there. The first graphics were entered as binary ones and zeroes, then programs were developed to run on the PC to convert graphic files into character maps displayable by the SMS graphics chip. The contract for game development at that time consisted of a series of 'milestones,' which I submitted to the client (in this case Imagineering) on the agreed-upon date and they paid the agreed amount. The first milestone was often to get some kind of image up, like a title page. Getting anything at all on the screen with these early video game machines was a challenge. The first milestone for R.C. Grand Prix was to get a car displayed onscreen you could rotate under player control. Then we laid out a simple track you could drive on." I mentioned before the 'staggered bricks,' so let him explain the proramming behind it. Refer to the following pictures from Nicktoons Racing (remember how I said the code was the same) to see exactly how the brick trick worked check this out and keep reading:

The pictures above are taken from the early development of Nicktoons Racing, and shows exactly what Scott's talking about because it was the same thing in R.C. Grand Prix, as you may have seen a bit in the huge map revealed earlier. "The typical TV image, bitmap image, computer graphic screen, video game screen, and video game 'world' design is laid out in a grid, simply a set of evenly spaced pixels or blocks of pixels in an even array of rows and columns of square areas, just like a piece of graph paper, basically. The Master System screen was made up of 32 characters horizontally and 24 characters vertically. Each character consisted of an array of 64 pixels, 8 high by 8 wide. The design of the racing screen of R.C. Grand Prix needed a isometric perspective in which horizontal lines were shown horizontally but vertical lines were shown as diagonal lines, thus the challenge presented in programming this aspect. Layouts using regular grids would have been too awkward to design to fit the format they wanted, so I came up with the idea of staggering successive rows of track sections in a brick pattern, as you see above." Scott thus created his own type of grid that as far as he knows has never been used in any other game, minus those based on R.C. Grand Prix's data. After this, more cars on the screen were programmed, which presented the problem with flickering.

We all know the problem. You're playing a game, perhaps R-Type, which is kind of notorious for this, and suddenly character sprites (enemies, whatever) start to flicker or sometimes even completely disappear, leaving you to suddenly get struck by a bullet or such that you didn't even see coming because visually it's gone, but in the programming still coming at you. Maybe you've even noticed that in some games when too many characters (sprites) line up horizontally on-screen they start to flicker or disappear. This is because "the system has graphics support that will only display eight sprites on the same horizontal line. There is only about 60 millionths of a second for an SMS graphics controller (the display chip that handles the timing of the electrical signals that create images on the screen from numbers in computer memory) to prepare a line of video for display, and only eigth logic circuits (electrical circuits that are able to store, compare and process binary impulses of electricity) are available for each line to prepare a line of sprites. After the eighth sprite on a give line is prepared, any other sprites that need to appear on that line will simply be missing." So programmers had to detect when "more than eight sprites will line up horizontally and pick alternately which ones will display and which will not. In R.C. Grand Prix, flickering cars or parts of cars was preferable to completely invisible cars, which could crash into you since you'd never see them coming. So, for example, if three cars are lined up horizontally, one or another is simply not drawn for a sixtieth of a second, in a clockwise fashion, so they can be seen by the player at all times. An additional finesse was made into R.C. Grand Prix that caused the computer-controlled cars to speed up, slow down, or turn left or right to help avoid this problem." Some of you may have noticed these aspects while playing, I know I did though it didn't bother me, kind of interesting to know why it's like that, makes you appreciate the declicacy of the program.

"It's pretty amazing what we had to do to keep things acceptable with limited hardware power in the consoles, and after this I created the AI for the computer controlled cars, built all the track layouts, background graphics, physics, sound, music, and title screens. For me, the hardest part to program for that game, was the physics. The SMS has no higher math capability so he had to fill one bank of the cartridge's memory with sine and cosine tables (pre-computed trigonometry)." What the hell does that mean? You're going to wish you didn't ask, and if you don't remember your math tough luck, go back to school!

"The SMS has a Z80 processor, which can do logic functions like AND, OR, NOT, XOR, and arithmetic functions like add and subtract. That's all. It can't multiply or divide or anything more sophisticated. You have to write programs to perform these functions, or supply look up tables. Say, if you needed to multiply by 7 really fast in a game, you'd create a table that had the numbers 0, 7, 14, 21, 28, etc. and you'd use the multiplicand to index a table of these values to just look up the product. That way, multiplying by a constant is done by adding (the multiplicand to the table start address). To do arbitrary multiplying and dividing requires a subroutine algorithm that works like what we learned in grade school, doing long multiplication or long division, but in binary instead of the decimal system. It's versatile but involves a time penalty. To do higher math like trigonometry, a Z80 in an SMS might need several seconds to do it straight. In R.C. Grand Prix four sine and cosine calculations need to be done 60 times a second, so that won't work. So, I created a program that ran on my PC that generates scaled trigonometric tables that he loaded into a bank of memory in the R.C. Grand Prix cartridge, and with a couple of additions, which the Z80 does instantly, I could find out how much the car needs to move and in what direction 60 times a second."

"In R.C. Grand Prix most of the CPU time was needed to replace the graphics of the cars (copy the image from ROM to screen RAM) when the car changed viewing angle," so everything explained above applies to aspects like this. "Another hard part in development was making the cars properly collide against each other and against the edges of the track." Remember the code I mentioned I was going to show you? Well, here it comes! I gave you some details on programming above, pretty basic and as you can see difficult, but let's look at just one aspect of programming R.C. Grand Prix in detail, purposely a difficult one, to show you exactly what goes in to making a game work. Keep in mind, this is just one part!

 
Copyright © 2024 Sega8bit. All Rights Reserved.
Contact Us