......ܲ. 
                          The Coding Sheets
          .          Issue Number 3 - 07/10/1995
                            Graphics in C
..  !mu ۲.
..... ۱

.To start off, here are a couple of pointers -
.#1 - For most applications, you do not want to use BGI graphics, for one
reason - they are slow.  I honestly would not be surprised if Borland stuck
some delay loops in there to slow them down.  Don't get me wrong; BGI has
it's uses.  But for most purposes, it is not what you want to use.
.#2 - In general, you do not want to use the BIOS.  It is slow as well.

We are now left with one route - accessing the VGA memory itself.  First,
however, I am going to violate rule #2.  In most cases, speed does not matter
for this function, the first you will call before using graphics - putting
the screen into graphics mode.  This is accomplished quite easily with the
following function -

void graphicsmode(void){
.asm{
..mov     ax,0013h
..int     10h
.}
}


This will put you into 320x200, 256 color mode.  To get back to text mode,
simply do this -

void txtmode(void){
.asm{
..mov     ax,0003h
..int     10h
.}
}

You may notice that both of these functions are using assembler to call int
10h, after putting in ax what mode they want to be in.  Int 10h, service 00
is set video mode, so this makes sense.  To test what video hardware the
computer has, use the following -

int detectgraph(void){
.int graph;
.asm{
..mov ah, 1ah
..mov al, 00h
..int 10h
..mov graph,bx
.}
.return graph;
}

It will return one of the following -

00h - No display
01h - MDA
02h - CGA
04H - EGA Color
05h - EGA monochrome
06h - PGA
07h - VGA monochrome
08h - VGA color
0Bh - MCGA monochrome
0Ch - MCGA color
0FFh - Unknown

You will probably want to run detectgraph() before graphicsmode() to make
sure the user has compatable hardware.  For example -

.int i;
.i=detectgraph();
.if(i<8)
..return 1;
.graphicsmode();

Ok, now we have done things that do not depend on speed.  We will now leave
the realm of the bios, and delve into deeper mysteries.  To start with - How
to Plot a Pixel.

The first thing to understand is that, for the purposes of plotting a pixel,
the VGA's memory begins at a000:000.  The following 320x200, or 64000 bytes
are what is on the screen.  So, to plot a pixel, we merely change that
memory.  Simple enough.  To plot a pixel, use the following code -

void putpixel(int x, int y, int color){
.poke(0xa000,x+(y*320),color);
}

To get a pixel, use this code -

int getpixel(int x, int y){
.int color;
.color=peek(0xa000,x+(y*320));
.return color;
}

Quick and to the point.  If you are bored and interested, you may wish to
compare the perforamnce of these pixel functions to BGI or BIOS pixel
plotting.  I'd be interested to see what you come up with.

Now, to change a color in the palette.  This is quite useful for everything
from fades to animations.  To change a color, use the following -

void writepal(int color_reg, int red, int green, int blue){
.outp(0x3c8,color_reg);
.outp(0x3c9,red);
.outp(0x3c9,green);
.outp(0x3c9,blue);
}

Simply put the color num in the VGA hardware port at 0x3c8, and then put the
values of red, green and blue in the port at 0x3c9.  Once again, simple.
To read a color's red, green and blue values, use the following -

void readpal(int color_reg, int red, int green, int blue){
.outp(0x3c7,color_reg);
.red=inp(0x3c9);
.green=inp(0x3c9);
.blue=inp(0x3c9);
}

Not hard, eh?  However, when you try this, you may notice some "snow".  The
way to avoid this is to wait until the monitor is retracting the screen.
The following code will do that -

void WaitRetrace(void){
.asm{
.mov dx,3DAh
.}
.loop1:
.asm{
.in al,dx
.and al,08h
.jnz loop1
.}
.loop2:
.asm{
.in al,dx
.and al,08h
.jz  loop2
.}
}

You may wish to add this function to the beginning of the writepal function.

This should cover the basics of graphics in Borland C.  I would like to give
credit to Denthor of ASPHYXIA from whose Pascal tutorial series I translated
some of this code.  If you write in pascal, I highly reccomend that tutorial.
If you use this code to write something neat/useful, I would like to see it.
Drop TCS a line...

.-Pluto


  You can contact The Coding Syndicate at :                               
    Virtual Utopia 303-695-9287                                           
  We need distros, coders, artists and musicians. Please contact us. NOW! 

