Mode13h
The Beginning of 3D/2D Graphics
Intro
Lots of people want to know how to do graphics but find most APIs like
OpenGL, DirectX etc too complex for a beginner, especially as they involve GUI code which follows a different approach from the simple dos programming Here, I will present a simple graphics mode, which can be easily used via dos console programming
What I will be covering
Part 1:Introduction to Mode13h (this part)
Part 2:Blazing:Lets speed up and burn (algorithms,double buffering)
Part 3:Dangers and Protection Systems (wait and see)
Part 4:Bitmap Loading and Animation (woooooo!!!!)
Part 5:Assembler,Let's go faster (world of supersonics,C++ code)
Part 6:Palette fun (let the artist live)
Part 7:Intro to 3D (::::::::::::::::)
Part 8:3D Star Fields (weee!!!!)
Part 9:Wrapup (end,alternate techs)
Ok, this series will take sometime or so. Maybe weekly updates. We go
slow in this article. Part 2 will be larger and contain code.
History of Mode13h
Here's a quote by a 3D programmer, Jacco Bikker (The Phantom):
In the old days, there was DOS. And in DOS, there was mode 13. Once
initialized, the unsuspecting coder could write to video memory, starting
at a fixed address, A0000 if I am correct. All this didn't block the computer, and worked on virtually every VGA card in the world. The mode allowed for output of 256 color graphics, and that was just fine, if you did it well.But then something really bad happened. SVGA cards started to appear
everywhere, and to make things worse, computers became fast enough
to do true-color graphics. From that moment on, nothing was certain
anymore. You had 15 bit graphics (for some VERY odd reason someone
decided to ignore a whole bit), 16 bit graphics, 24 bit, 32 bit, and random
orderings of the color components in these arrays of bits. You could for
instance encounter a card that did RGB, but also BGR, or RGBA... So the
VESA standard was invented. This made things bearable again.
So, anyway Mode13h is a graphics mode from the past, with a low resolution so don't compare it with the latest stuff you see in the games. People do say Mode13h is dead, it's not true, even though no game company makes games in Mode13h anymore, it will serve as nice intro beginners, as it has done before. And btw, lots of games are still being made in mode13h by hobbyists.
Let the coding begin.....
Tools of the Trade
Mode13h does not work in the standard console mode, so you will have to change a few settings on you compiler. You will have to use DOS, Large memory model. Don't worry too much. Just getting into mode13h or getting out of it is different on different compilers the rest is quite the same. The simplicity comes from the fact that you can write to the screen pixels as if you were writing into a char array. It simple to set up x, y coordinate system in Mode13h.
You can get TurboC for Borland's site for free. It is quite good if you want an easy way to compile you programs. Remember to compile in the LARGE memory model!
To compile in Borland C: bcc -ml yourprogram.c I would still recommend that you get a C++ compiler to compile your programs as I will use stuff like classes later on. And it's much easy to code if you can use the advanced features which C++ offers over C.
Compilers
Borland C++ (My fav)
DJGPP (Free,Very Good,Protected mode programs)
Dev-C++ (Dont know,heard somewhere it can do Mode13h)
Headers
Keep all functions you get in a header files. That way you won't have to modify all you programs to change something. Standard Headers to include:
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <mem.h>
Borland (Should work on most compilers)
#define VIDEO_INT 0x10 /* the BIOS video interrupt. */
#define SET_MODE 0x00 /* BIOS func to set the video mode. */
#define MODE_13H 0x13 /* use to set 256-color mode. */
#define TEXT_MODE 0x03 /* use to set 80x25 text mode. */
#define SCREEN_WIDTH 320 /* width in pixels of mode 0x13 */
#define SCREEN_HEIGHT 200 /* height in pixels of mode 0x13 */
#define SCREEN_SIZE SCREEN_WIDTH*SCREEN_HEIGHT
#define NUM_COLORS 256 /* number of colors in mode 0x13 */
byte *VGA=(byte *)0xA0000000L; /* this points to video memory. */
void set_mode(byte mode)
{
union REGS regs;
regs.h.ah = SET_MODE;
regs.h.al = mode;
int86(VIDEO_INT, ®s, ®s);
}
Use it as:
set_mode(MODE_13H); //to get into mode13h
set_mode(TEXT_MODE); //to get back into the normal mode
DJGPP
void set_mode(byte mode)
{
union REGS regs;
regs.x.ax = mode;
int86(VIDEO_INT, ®s, ®s);
}
Properties of Mode13h
It's 320 pixels wide and 200 pixels high. There are 256 colors available, and their values fit in 1 byte, i.e. the size of a char. I mentioned earlier that putting a pixel was as simple as putting a char in an array. The VGA memory is 64000 (320 * 200) bytes in size. Location(0,0) is at the top left hand corner of the screen. So Mode13h is simple to implement and it is fast.
Drawing In Mode13h
Ah the section you been all waiting for. Here we will just discuss putting a pixel and clearing the screen. Later on I will talk about algorithms for drawing lines, circles, boxes etc. They all require you to be able to put a pixel any way.
void pixel(int x,int y,byte color) //Puts a pixel by writing directly to memory
{
VGA[y*SCREEN_WIDTH+x]=color;
}
void clear(int color)
{
memset(VGA,color,SCREEN_SIZE);
}
Really simple,eh? Look at the function for putting a pixel to the screen. We are simply writing to the VGA memory as if it was just a char array.
Go ahead, try something,anything!You should be able to draw straight lines with simple functions.
void line_horz(int x,int y,int len,byte color) //Draw horizontal lines
{
for(int i=0;i<len;i++)
{
pixel(x+i,y,color)
}
}
Stuff for You to do
- Of course, make a function to draw vertical lines.
- funtion(s) to draw square,rectancles.
- Do benchmark tests.(findout how fast the system is)
Ending Notes
Next edition, we will talk about double buffering and speeding up our drawing. Yea, blazing fast. Also you will get a few algorithms (line, circle) and some good stuff.
Have fun.