Topic : DOS Game Programming
Author : Alexander Russell
Page : 1 Next >>
Go to page :

Alex Russell's DOS Game Programming tutorial
by Alex Russell (

This tutorial was copied from with the kind permission of Alex Russell!


There are a number of tutorials available for the intermediate game programmer, but there are very few good tutorials for beginners who have never drawn a pixel on the screen. A quick search on the net reveals hundreds of sites devoted to 3D, polygons, texture- mapping and other advance topics, but the beginner has no where to get started. This tutorial is for C programmers who want to get an introduction to game programming.
The course will be done in C using dos 16bit real mode. The video mode is 0x13 (320x200, 256 colours). This has been chosen for simplicity, and availability.
Prerequisites:If you do not have these prerequisites you will find yourself consulting your c manuals quite a bit. I highly recommend that you have at least mastered the basics of c syntax. Here is a link to Yahoo's c/c++ page, including tutorials, and this is a good page for C Beginners too.
Required:c, including: pointers, structures, functions, basic data structures (e.g. linked list, stack), and file i/o
OptionalASM: x86 - there is a little bit of ASM code used to access hardware.
Why DOS?
DOS is dead, but it is a great environment for learning the underlying principals of game programming. All the main principals that are used for any platform can be learned in an easy to use, and popular operating system.
All code will be taught in c, but ASM equivalents will be supplied for all primitives with marked chapters on request.
OutlineChapter 1
Quick overview of c
dynamic memory allocation
include files
file i/o
memory models, why we will use medium
global variables, and other evils

Entering mode13h, via int86
mode13h details
saving and restoring old video mode
Chapter 2
Double buffering vs. page flipping, and syncing to vertical retrace
Graphic primitives
horizontal lines
vertical lines
arbitrary lines
filled rectangles
Chapter 2.1
More graphic primitives
solid sprites
transparent sprites
RLE transparent sprites
restoring backgrounds
graphic text

Loading images from drawing programs
Chapter 3
bouncing pixel on black
bouncing sprite on black
bouncing sprite on fancy background
multiple bouncing sprites
Chapter 4

combining all user input in one event queue
Chapter 5
Collision detection
rectangles only

Colour management
colour cycling
reserved colours for common elements
dynamic colours for various parts of a game

Timing a game, and game design
* separating drawing from logic *
the PC timer
too slow
too fast
Chapter 6
Break Out
simple animation
collision detection
player control
Each chapter is ended with a number of programming exercises. For $25.00 US I will mark, and correct all work associated with one chapter's exercises. Material to be marked can be emailed, but no marking is done until AFTER I receive a Money Order, in US funds, for the total amount via snail mail. There is no need to do every chapter. Pick the chapters that you feel you need the most help on. Having a chapter re-marked also costs $25.00. Marked exercises are returned by email.
You will also receive ASM versions of all the graphic primitives with the first chapter you pay to have marked if you request it.
When emailing work to be marked include: name, email id, a code word that will appear with the snail mail, and the emailed assignment. The snail mail should include: a money order payable to "Alex Russell" in the amount of $25.00 per chapter, in US funds, your name, email id, and the password. Pick any nonsense phrase you like for the password. Assignments on floppy disk will also be accepted with payment.
Email me at for my snail mail address.

Chapter 1Quick overview of C
I am assuming you are already comfortable programming in c. This chapter is meant to be a quick over view of commonly used programming techniques in dos games. If everything here is not familiar I suggest you seek out a good c tutorial.
PointersGames use lots of memory, and most of it is accessed via pointers. Pointers are fast and, once you learn how they work, simple.
A pointer is a variable that holds the address of a data item. c pointers have an associated type, and generally only point to one type of thing.
char *t1;This declares a pointer to a character. It does NOT define where it points.

char *t1;
strcpy(t1, "hello world");This will crash many computers. We have declared the pointer t1, but we are now trying to copy data to it, BEFORE we make it point to a valid range of memory.

char *t1;
strcpy(t1, "hello world");This will work. We have declared t1 to be a pointer to memory holding characters. We have made t1 point to a valid range of memory,100 bytes long, using the function malloc(). Then we have copied the data "hello world" to the memory t1 points to.
malloc() is a function that returns a pointer to a range of memory that your program can safely write to. It takes one parameter which specifies the number of bytes we want. It returns NULL if the requested memory is not available.

int *it1, *it2;

int i;



for ( i=0; i < 100; i++ )





This code makes it1 point to a range of memory large enough to hold 100 integers. The operator sizeof returns the size in bytes of a C data type. Then the memory pointed to by it1 has the values set to 0 through 99.
*it1=i;The '*' 'dereferences' a pointer. *it1 means 'the value pointed to by it1'. This line of code sets the integer that it1 is pointing to to the value of I.
i=*it1;This line of code sets i to the value of the integer that it1 is pointing to.
i=it1;This line of code sets i to the value of the ADDRESS that it1 is currently pointing to.
it1++;This makes it1 point to the next integer.
it1+=5;This makes it1 point to the 5th integer from where it is now. The c compiler knows what the pointer is pointing to and automatically adjusts how far it moves pointers by the size of the data it is pointing to.

typedef struct


   char s1[90];

   int I,j,k;



   data_t data, *dp;

   strcpy(data.s1, "hi there");





   strcpy(dp->s1, "bye know");





   memcpy(dp, &data, sizeof(data_t));

Here we have defined a struct of type data_t, and declared a data_t, and a pointer

to a data_t. dp->i; means the value of member i of the struct that dp points to. It is

short hand for *(dp.i); The memcpy() copies data to dp.

int foo(int x, int y)


   return y*320 + x;


This is a very simply function that takes two integers as parameters, and returns an integer. If this is not a very familiar concept I suggest you seek out a c tutorial.
#include <stdio.h>The above line `includes' stdio.h in the source code. It is exactly the same as inserting the file stdio.h in the source file. Include files should never contain code or definitions (e.g. global variables). Only declarations, prototypes, defines, etc. should be in include files. When making your own include files the following code should go at the top and bottom to prevent it from being included more than once. It is a common practice to have an include file include all the files required to make it compile correctly. This can lead to the same file being included more than once if you do nothing to prevent it.

/* test include file */

#ifndef DEF_TEST

#define DEF_TEST 1

typedef unsigned char BYTE;


The #ifndef, #define, and #endif together will prevent an include file from being included multiple times. Simply change the DEF_TEST to DEF_filename for each include file.
The standard c runtime functions fopen(), fwrite(), fread(), fseek() etc. will be used for most file i/o in these examples. If these functions are not already familiar then I suggest you seek out a C tutorial. You should be comfortable reading existing files, and writing out new files.
We will be using the MEDIUM memory model which is NEAR data, and FAR code. This means that the use of the far heap will require the use of farmalloc() and farfree().
In general, global variables, and goto's are BAD, but we will use a few global variables where it makes sense.
While most of the basic graphic and animation techniques presented here are generic enough to be useful in any project, the user i/o (keyboard, mouse, joystick) is so specific to DOS that I will present the code to do it with minimal explanations.
Entering mode13h, via int86This course will be using mode13h exclusively. This is 320x200, 256 colours. Video memory is laid out in a simple rectangular grid where 0,0 is at the top left, x increases to the right, and y increases down. Each pixel is one byte, and its colour is determined by the colour palette it indexes. Mode 13h has a colour palette of 256 colours, each of which is defined by 6 bits of red, blue, and green.

Pixel coordinates are always presented as a pair of numbers indicating the X and Y position of the pixel. For example, the black pixel above is at location (3,1) Please note that the top left corner is (0,0) NOT (1,1). The bottom right pixel is (319, 199). This linear arrangement of video memory is common to most modern video systems. While it is natural to think of video memory as a grid like this, it is actually just a long array of memory. More on

Page : 1 Next >>