| Graphics in Mode 13h |
| Me | Home | Links | Tutorial | |
Mode 13h is a VGA graphics mode that is easily accessible from DOS programs. It offers a resolution of 320 by 200, with 256 colors (meaning one byte per color). While it may not be the best looking graphics mode there is, it's very easy to use, and can go at a good speed. In addition, it's really only useful for DOS games, so if you want to write a Windows program, you probably want to use something else.
The following code will set Mode 13h in Borland C:
/* Borland C - Set Mode 13h. */
#include <dos.h>
void setmode13h()
{
union REGS r;
r.x.ax = 0x13;
int86(0x10, &r, &r);
}
And here is the DJGPP version:
/* DJGPP - Set Mode 13h. */
#include <dpmi.h>
void setmode13h()
{
__dpmi_regs r;
r.x.ax = 0x13;
__dpmi_int(0x10, &r);
}
The code works by calling BIOS interrupt 0x10, which is the video interrupt.
r.x.ax is a word (16 bits). Its high byte, which is 0, tells the interrupt
to set the video mode to whatever is in the low byte of r.x.ax, in this case
0x13, for mode 13h.
Now you have the computer in mode 13h. The next step is setting the color of individual pixels on the screen. The way video memory works in mode 13h is fairly straightforward. Basically, there is one big array in memory, each element of which controls the color of one pixel on the screen. Since we need a byte to hold the color of a pixel (there are 256 colors in mode 13h, and a byte can hold 256 numbers, 0-255), this array is an array of chars. Your program does not have to create this array, beacuse it already exists. It is located at segment A000h, offset 0000h. The first element of the array, at A000:0000 controls the upper-leftmost pixel of the screen. The second element, at A000:0001 controls the pixel immediately to its right, and so on for the first row of pixels. The first pixel in the second row (the 321st pixel, overall), is at A000:0140, or 320 bytes after the first pixel. The of pixels continue in the same way, so pixel (x, y) is at segment A000h, offset (x + y * 320).
Some sample code:
And in DJGPP:
/* Borland C - Setpixel. */
void setpixel(int x, int y, unsigned char color)
{
unsigned char far *vram = (unsigned char far *) 0xA0000000l;
vram[x + (y << 6) + (y << 8)] = color;
}
The sample code uses (y << 6) + (y << 8), instead of (y * 320) because
the former is slightly faster. If you don't understand what (y << 6)
means, go to my basics page.
/* DJGPP - Setpixel. */
#include <sys/farptr.h>
#include <go32.h>
void setpixel(int x, int y, unsigned char color)
{
_farpokeb(_dos_ds, 0xA0000 + x + (y << 6) + (y << 8), color);
}
Another good thing to know is how to change the palette. The palette is what turns that number from 0 to 255 into an actual color. To set a color in the palette, you tell the computer the red, green and blue components you want that color to have. The red, green and blue components range from 0 to 63, where 63 is the brightest, and 0 is nothing of that color.
Here is code to set the palette:
/* Borland C - Palette Set. */
#include <dos.h>
void setcolor(char color, char r, char g, char b)
{
outportb(0x3c8, color);
outportb(0x3c9, r);
outportb(0x3c9, g);
outportb(0x3c9, b);
}
DJGPP:
/* DJGPP - Palette Set. */
#include <pc.h>
void setcolor(char color, char r, char g, char b)
{
outportb(0x3c8, color);
outportb(0x3c9, r);
outportb(0x3c9, g);
outportb(0x3c9, b);
}
Here's how to get back into text mode:
/* Borland C - Back to text mode. */
#include <dos.h>
void settextmode()
{
union REGS r;
r.x.ax = 0x3;
int86(0x10, &r, &r);
}
And here is the DJGPP version:
/* DJGPP - Back to text mode. */
#include <dpmi.h>
void settextmode()
{
__dpmi_regs r;
r.x.ax = 0x3;
__dpmi_int(0x10, &r);
}
Going back to text mode uses the same code as getting into mode 13h, you
just use 0x3 instead of 0x13.
| Me | Home | Links | Tutorial |
David A. Mellis / stendahl@imsa.edu / Last Modified - June 2, 1998