» How to code your own handheld game simulator
Note: this tutorial hasn't been updated since 2000.
» Table of contents
Many people often ask me the way I build my simulators.
To make your own simulator, the first thing you need is the electronic
I work on a PC with P166MMX processor, 32MB RAM, a table scanner, a SB16
compatible sound card and a very cheap microphone.
» Chapter 1: Acquiring images
Let's start by getting the scans of the videogame.
Now let's choose the DPI setting of the scans.
OK, let's scan the game now.
LCD screens usually have a polarizing filter, which makes the sprites have some kind of "direction" to see them best. Place the handheld game so that the light of the scanner enlightens the upper side of it (this will make the light source come from the right direction to see the sprites the best way!).
Now try to get ALL the sprites turned on.
Now check out your scans. Are they detailed enough? If so, then continue
to chapter 2, otherwise read below.
If the game works with LEDs (or VFDs) and not with LCDs, this procedure
won't work at all: the light of the LEDs will disturb the scanner and
you'll get messed graphics. Use a digital camera instead.
» Chapter 2: Retouching the scanned images
Open all of your images with any drawing tool and check them out
Now get the colour of one sprite ("dropper" tool with Paint Shop Pro) and note its properties onto a paper sheet: this becomes your reference colour for all sprites. Then take the "pen" tool and retrace all the contours for all of the sprites. This may be the longest and most boring job, but the result is guaranteed!
After tracing each contour, "fill" the sprite with the same colour, but you may prefer to use a slightly darker colour for the inside and a lighter colour for the contour (or vice-versa). That's your choice.
When all sprites have been retouched, proceed and trace a rectangle around the borders of the LCD screen; then copy that rectangle and its content to clipboard. Finally paste as "transparent selection" to the background image, placing the rectangle in the correct position!
Now you can save this image as a kind of repository for all of your sprites.
At this point, you'll have TWO background images: the former having no sprites on it (let's call it BASE.BMP and the latter having the entire LCDset on it (let's call it SPRITES.BMP).
Next step is getting single files for sprites: one image per each
Repeat this procedure per each sprite, and save all sprites images in a
UPDATE (Aug 23rd, 2000): Robert Kacsich, author of the great "Coleco Head to Head" and "Neko Don Don!" simulators, sent me a small article to show me a different retouching process, which he uses for his Visual Basic simulators. Check it by clicking here.
Now you can work on sounds...
» Chapter 3: Getting and cleaning beeps
You'll have to use your microphone now.
Now play the recorded sounds and check them out. If the WAV file's volume
is too low, you may pump it up until it reaches a suitable volume level,
but keep an ear to the quality anyway.
Then proceed with the sound cleaning, using a simple tool as GoldWave or CoolEdit. Trim the main sound sequences and you'll obtain a few WAV files. Each WAV file must contain one beep only or an entire music; but there must not be silence between the beginning of the WAV file and the beginning of the music, otherwise sounds won't be synchronized to the game!
Take note of the duration of each sound: this is useful to measure the
speed of the game!
Now you're ready to proceed with Delphi.
» Chapter 4: Setting the main form
Before getting started, let's set the scaled property of your form to "false", so it won't be resized by Windows if you use the "big fonts" setting; then use a 96DPI resolution. Don't set the formstyle to "resizable" and then make the maximize and minimize system icons disappear from the main bar menu! By doing so, you'll be sure that the form will always be viewed the proper way!
Place your BASE.BMP image in the form, and let the form's client
height and width have the same size as the image.
You may want to simulate the pressing of the buttons by using a graphic
effect. You'll have to get a piece of BASE.BMP (containing the
button only), select the button shape only, and save it as JPG (let's
call it BUTTON1.JPG) (no quality loss) as a separate image: you'll
use it in an Image.OnMouseDown procedure.
You may also want to let the form be dragged around your desktop by clicking on it: make a Form.OnMouseDown and a Form.OnMouseMove procedure to manage this. These procedures MUST be associated to EVERY sprite in the LCD screen and to the background graphics, but NOT to buttons or switches!
» Chapter 5: Starting the game
You'll need many global variables: time/demo/game modes, score, hiscores, lives left, current level; but you'll also have to define some variables to enable/disable controls (depending on game events) and to make the simulator understand whether you're playing or the game is in "demo" or "time" mode.
You'll have to place ALL of the initializations required in the
Create a few procedures to simulate all buttons presses, then start
managing with timers.
» Chapter 6: Timer components
The Timer component is one of the most important resources for this kind
procedure Timer_ATimer (Sender: TObject); begin Img_LeftSprite.visible := not Img_LeftSprite.visible; end;
the result is that at every 0.4 seconds the image called "Img_LeftSprite" will shift from visible to invisible and vice-versa repeatedly.
Remember: timers can be active or inactive, depending on what you
wish to do with it. Also remember that the interval property can
be redefined every time you want, letting you use a single timer
component to make many variations to your routines!
» Chapter 7: MediaPlayer components
If you wish to include wave samples of the original game sounds, this
resource becomes necessary.
You must hide the MediaPlayer components by setting their "visible" properties to false: seeing them is not useful at all!
Make your Form.OnCreate procedure load and open all wav files at once:
MPlay_MusicStart.FileName := '.\SOUND\START.WAV'; MPlay_MusicStart.Open; MPlay_MusicBeep3.FileName := '.\SOUND\BEEP3.WAV'; MPlay_MusicBeep3.Open;
and so on...
Then you'll just need to place instructions like
where <????> means the reference name to the MediaPlayer in your in-game procedures. Easy isn't it?
» Chapter 8: Moving your character's sprite
First, set your form's keypreview property to TRUE, otherwise the Form.OnKeyPress, Form.OnKeyDown and Form.OnKeyUp procedures won't work at all. You need these procedures to manage the movement of your character's sprite.
You may either use the Form.OnKeyDown and Form.OnKeyUp
events or the Form.OnKeyPress one only, depending on the game's
The Form.OnKeyDown procedure must contain ALL of the movement routines; if your sprite can just move from left to right and vice-versa, your procedure will include something like this:
if (GameStarted = true) and (Controls = true) then Controls := false; // disables controls until key is released if key = VK_LEFT then if Position > 1 then begin Char_Sprite[position].visible := false; // hides the "old-positioned" sprite Position := Position - 1; // updates the sprite's position Char_Sprite[position].visible := true; // shows the "new-positioned" sprite end; if key = VK_RIGHT then if Position < 3 then begin Char_Sprite[position].visible := false; // hides the "old-positioned" sprite Position := Position + 1; // updates the sprite's position Char_Sprite[position].visible := true; // shows the "new-positioned" sprite end;
The Form.OnKeyUp procedure will just set the Controls variable to true:
if (GameStarted = true) and (Controls = false) then Controls:=true;
» Chapter 9: LCD numbers display
The conversion from pure integer numbers to a sequence of LCD numbers is quite difficult, and requires a good knowledge of some arithmetic functions as mod and div.
The first thing you must do is to place the numbers' images anywhere on
the form, and then hide them (ex: Number5.visible:=false).
NumberPosition2.picture := Number5.picture; // (*)
The best way to call images' pictures is by associating them to an
array of TImage and then by indexing them.
procedure TForm1.FormCreate(Sender: TObject); begin Number_Array := Number0; Number_Array := Number1; <...> Number_Array := Number9; end;
so the previous instruction (*) becomes
Number_Position2.picture := Number_Array.picture;
Next step is splitting the score in its units, tenths, hundreds and so on: learn how to use the mod, div, IntToStr and StrToInt functions: that's all.
» Chapter 10: Conclusions
I wish you enjoyed this small tutorial. Well, I know that my English is
all but perfect, and I wish I've been clear enough with my
If you have any questions feel free to ask.
Good luck to you, young programmer!