VGA Routines I
This file contains the code for the graphics routines used in chapters one to four.
Click here to return to the main page.
Before you start reading this page, you might want to know that I assume a knowledge in C/C++ and some understanding of the PC's hardware (Look for the PC Game Programmers Encyclopedia, it can be found here (This link is slightly old and I'm writing this page on a computer without internet access, I'll check it later).
Well, here it is. I've devided the package into two pieces, the header file and the actual code.
GFXMAN.H
// Header file for the GFXMAN.CPP file.
// Credit Ware, give credit if you use it. Written by Johan E. Thelin (e8johan@etek.chalmers.se)
// Prototypes
void SetVGA(void); // Enters mode 13h
void SetText(void); // Returns to text mode
// Draws a line onto the screen
// Credits goes to Mark Feldman, see PCGPE for more info
void Line(int x1,int y1,int x2,int y2,unsigned char colour);
// Plots a pixel onto the screen
void Plot(int x,int y,unsigned char colour);
void Cls(void); // Clears the screen
void WaitRetrace(void); // Waits for a vertical retrace
The line function is written by Mark Feldman, see the PC Game Programmers Encyclopedia for more info.
The following file contains the actual code for the routines.
GFXMAN.CPP
// GFXMAN.CPP - Designed by Johan E. Thelin
// Line routine by Mark Feldman
// Please don't use without crediting those who deserve credits!
// Includes
#include <mem.h> // Contains the _fmemset() function
#include <dos.h> // Contains the int86() function
#include <math.h> // Contains the abs() function
#include "gfxman.h"
void SetVGA(void)
{
union REGS r;
r.x.ax=0x0013; // Set register AX to 0013h
int86(0x10, &r, &r); // Call the BIOS
}
void SetText(void)
{
union REGS r;
r.x.ax = 0x0003;
int86(0x10, &r, &r);
}
void Plot(int x,int y,unsigned char colour)
{
if((x>-1)&&(x<320)&&(y>-1)&&(y<200))
{
char far *adr;
unsigned int offset=y*320+x;
adr=(unsigned char far *)(0xA0000000L+offset);
*adr=colour;
}
}
void Line(int x1,int y1,int x2,int y2,unsigned char colour)
{
int i, deltax, deltay, numpixels,d, dinc1, dinc2,x, xinc1, xinc2,y, yinc1, yinc2;
deltax = abs(x2 - x1);
deltay = abs(y2 - y1);
if(deltax >= deltay)
{
numpixels=deltax + 1;
d=(2*deltay)-deltax;
dinc1=deltay << 1;
dinc2=(deltay-deltax) << 1;
xinc1=1;
xinc2=1;
yinc1=0;
yinc2=1;
}
else
{
numpixels = deltay + 1;
d = (2 * deltax) - deltay;
dinc1 = deltax << 1;
dinc2 = (deltax - deltay) << 1;
xinc1 = 0;
xinc2 = 1;
yinc1 = 1;
yinc2 = 1;
}
if(x1 > x2)
{
xinc1 = - xinc1;
xinc2 = - xinc2;
}
if(y1 > y2)
{
yinc1 = - yinc1;
yinc2 = - yinc2;
}
x = x1;
y = y1;
for(i=1;i<=numpixels;i++)
{
Plot(x, y, colour);
if(d < 0)
{
d = d + dinc1;
x = x + xinc1;
y = y + yinc1;
}
else
{
d = d + dinc2;
x = x + xinc2;
y = y + yinc2;
}
}
}
void Cls(void)
{
_fmemset((void far*)0xA0000000,0,64000);
}
void WaitRetrace(void)
{
char check=8;
while((check&8))
check=inportb(0x03da);
while(!(check&8))
check=inportb(0x03da);
}
Again, credit goes to Mark Feldman for the line routine.
Compilation
To use these routines, place them in a folder and compile GFXMAN.CPP to a .OBJ file. Then include the GFXMAN.H in your code and link the .OBJ file to your code.
Here is how it's done using Borland's Turbo C 3.0 :
>tcc -c GFXMAN.CPP This produces a .OBJ file.
>tcc MINE.CPP GFXMAN.OBJ This compiles your file and links it to the .OBJ file.
If you experience any trouble using this code with any compiler, please mail me about it at e8johan@etek.chalmers.se and I'll try to help you out. Please mail even if you have managed to overcome the problems and tell me about your solution.
Here follows a test application, it doesn't do much but it tests all functions.
TEST.CPP
// Tests the routines in the gfxman.cpp file
// Written by Johan E. Thelin (e8johan@etek.chalmers.se)
// Please, don't use these routines without crediting those who deserve it
#include
#include "gfxman.h"
void main(void);
void main(void)
{
SetVGA();
for(int y=0;y<200;y++)
Line(0,0,319,y,(unsigned char)y);
for(y=0;y<320;y++)
Plot(y,199,(unsigned char)(y%256));
getch();
SetText();
}
Just compile this together with the gfxman.obj file and run test.exe from the dos prompt. (The result is supposed to be a triangle from the top-left corner to the right-top and right-bottom corners, filled with differently coloured lines emerging from the top-left corner. The bottom line of he screen will be consisting of a multicoloured line.)
Response and development
I would appreciate any comments and ideas concerning the improvement of this code (I currently use a version of this code that supports circles, ellipses, triangles (solid and gourand filled), put and get, text, etc.). If you make any modifications, please mail me about them. I love getting response, both positive and negative (of a constructive nature).
Remember, the more response I get, the better this page will get!
If I don't get any response, I won't know what you want me to add to these pages.
You can reach me at e8johan@etek.chalmers.se.
[ Main Page ]
Copyright©1997 Johan E. Thelin