///////////////////////////////////////////////////////////////////////////
// 09. Svgalib Primer                                                    //
                                
//     By: Brent York                                                    //
//         AKA ThaDragon @EFnet's #c                                     //
//     Email: york@nbnet.nb.ca                                           //
//         Nuclear Winter Entertainment                                  //
//         Professional Coder for Spheringer Technologies Inc.           //
///////////////////////////////////////////////////////////////////////////

        First off, Im not going to teach you everything you ever needed
to know about graphics without a flash, double buffering whatever.  If
you want to learn that please by all means go to x2ftp.oulu.fi in the
/pub/msdos/programming/docs directory and get the denthor tutorials.  Sure
they are pascal+assembly but the concepts are sound.


        Secondly, this tute isn't an "everything you ever wanted to know about
svgalib" tute, and I never meant it to be.  Sorry if I come off as being
mean ;} but I figure if youre ready to use svgalib, you already know what
Im talking about.  My plan is to simply cover some of the functions
svgalib has to offer that will allow us to create a program that uses
320x200x256 graphics.


        By the end of this you should know enough to at least write the
graphics routines you should already have written for DOS.  Our example
program (attatched to this document) is simply 2d bumpmapping.  Dont
worry about where I got the palette.


        Note that Im not going to teach you bumpmapping, the only code
you will have learned by the end of this is the normal routines you would
have, and how to use the mouse in svgalib. These routines are in
graphics.c/graphics.h and mouse.c/mouse.h, everything else that does the
bumpmapping etc is in bmap.c/bmap.h, and does not pertain to this
tutorial directly.

        
        If you want to learn 2d bumpmapping, by all means get the doc on
it on the ftp site in the directory shown above.


        So without further ado, lets plunge in and get buried in bits =}.


=============================================================================


        Svgalib is a graphics library provided for people to make console
based graphical apps.  Sdoom, and Squake are two such apps.


        These "routines" reside in libvgagl, and libvga, and its headers
are, vga.h, and vgagl.h respectively.  Both must be included for svgalib
routines to work (As one relies on the other).  As always, gcc is a one
pass linker therefore you link with -lvgagl -lvga.  Its always in this
order.

        
        Basically with svgalib all the wonderful graphics routines are
written FOR you. However, if you want them to conform to your lib you can
easily #define the function names into macros or something.  We however
WILL NOT do that, our routines will be plane jane svgalib.


        Ok, first off the routines one needs for a decent graphics
library (all other routines can be made from these):

set video mode routine
vertical retrace routine
flip to screen routine
setpalette routine
getpalette routine
setpalette range routine
getpalette range routine

and along with that scince you have to init svgalib youll have init, and
deinit functions.


The Init Function:
==================

        The init function usually consists of a simple call to
vga_init(); but can consist of any code you want to actually init your
library as well.  The vga_init() function simply initializes the vgagl
library.  It returns void and receives void, therefore its function
prototype is:

void vga_init(void);

******************************************************************************
IMPORTANT NOTE: If youre concerned about security (AND YOU SHOULD BE!)
call this function RIGHT AFTER you open the main function:

int main(void) {
  vga_init();

etc.

This is because svgalib programs must be SUID/SGID root to run!, this
call switches the uid/gid to that of non-root thusly eliminating a huge
security hole!
******************************************************************************


The "setvideomode" routine:
===========================

        The setvideomode routine should use the defines in vga.h for
video modes.  This is due to the fact that it accepts different numbers
for video modes than interrupt 10 in dos.
        
        Therefore lets cut and paste some vga.h (only text & 256 color modes)

#define TEXT         0          /* Compatible with VGAlib v1.2 */
#define G320x200x256 5
#define G320x240x256 6
#define G320x400x256 7
#define G360x480x256 8
#define G640x480x256 10
#define G800x600x256 11
#define G1024x768x256 12
#define G1280x1024x256 13       /* Additional modes. */


Note that these and the rest of the video modes can be found in
/usr/local/include/vga.h, and you should take a look at this file if
youre really interested in learning SVGALib.


These are the names youll actually want to use to change to these video
modes, because its more readable and more understandable.  Of course
one could make thier own defines and use those but the numbers MUST be
the same.


The functions you will be using to set the video modes are called
vga_setmode() and gl_setcontextvga(), and thier prototypes are as follows:

int vga_setmode(int mode);
int gl_setcontextvga(int mode);

so basically:

vga_setmode(G320x200x256);
gl_setcontextvga(G320x200x256);

will get you into 320x200x256 linear video mode.



the "vertical retrace" routine
==============================

        The vertical retrace routine is simply a call to
vga_waitretrace(), whose function prototype is void vga_waitretrace(void);

        This is obviously used to prevent flicker and fuzzy palettes.
        


The "flip to screen" routine.
=============================

        This routine is essential because you will be writing to a
virtual screen and then flipping that virtual screen to video ram during
a vertical retrace.  However due to memory protection contraints, YOU
cant do it directly without the help of svgalib...

        Therefore, the thing we call for this is gl_putbox().  Its
prototype is:

void gl_putbox(int x, int y, int w, int h, void *dp);

        x, and y are where to put the virtual screen... w and h are the
width and height of our screen, and void *dp is our virtual screen (we
need not cast it to void *).

Therefore to flip the virtual screen vscr (a char * pointer), we would
call it as follows:

gl_putbox(0,0,320,200,vscr);



The "setpalette" routine:
=========================

        Firstly, RGB's in svgalib are in the same terms they are in DOS,
this means 0-63 not 0-255.  To set the palette you use gl_setpalettecolor().
gl_setpalettecolor()'s function prototype is as follows.

void gl_setpalettecolor(int c, int r, int g, int b);

Therefore:
  gl_setpalettecolor(0,0,0,1);

will make color # 0 bright blue.



The "getpalette" routine:
=========================

        To get a palette in svgalib is done with gl_getpalettecolor().
gl_getpalettecolor()'s function prototype is as follows:

void gl_getpalettecolor(int c, int *r, int *g, int *b);

which means you pass it a color, an address of an int for r, an address
of an int for g, and an address of an int for b.

In other words:

gl_getpalettecolor(0,&r,&g,&b);

will get the rgb values for color 0.




The "setpalette range" routine:
===============================

        A set palette range routine sets all 256 colors of the palette
via a 768 byte buffer structured as rgbrgbrgbrgbrgbrgb......etc.

        The function to set the entire range of palettes is
gl_setpalette(), its function prototype is as follows:

void gl_setpalette(void *p);

So pass it an array of 768 unsigned chars and let it do its thing.



The "getpalette range" routine.
===============================

        A getpalette range routine will get the entire palette into a 768
byte buffer of bytes in the format rgbrgbrgbrgbrgbrgb....etc...

        The function to set the entire range of palettes is
gl_getpalette(), its function prototype is as follows:

void gl_getpalette(void *p);

pass it an array of 768 unsigned char and get all the rgb's for every
color on the 256 color palette.



The DeInit function.
====================

        The deinit function should only be part of your library to free
the ram taken by the palette buffers if they were dynamically allocated.
It should also free the virtual screen which should *ALWAYS* be
dynamically allocated.





=============================================================================

        As a special add on, Im going to show you how to use the mouse functions
in svgalib to create a "mousestatus" routine that will return the x, and
y, positions and the current button status.

The extra header we will need is called:

vgamouse.h

The routines we will be using are:

mouse_init();           (to init the mouse)
vga_getmousetype();     (to get a reliable mouse type)
mouse_update();         (to update the mouse status)
mouse_getbutton();      (to get the button status)
mouse_gety();           (to get the y location)
mouse_getx();           (to get the x location)


firstly, in the program you must call mouse_init() as follows:

mouse_init("/dev/mouse",vga_getmousetype(),MOUSE_DEFAULTSAMPLERATE)

itll return -1 if it works, itll return 0 if it doesn't.

Then our mouse routine:

void mousestatus(int *x, int *y, int *buttons) {
  mouse_update();
  *x=mouse_getx();
  *y=mouse_gety();
  *buttons=mouse_getbutton();
}

Thats prettymuch it, call it like mousestatus(&x, &y, &buttons);



Hope the svgalib tutorial covered what you needed to get you started.
Look at the example source graphics.c/graphics.h/mouse.c/mouse.h, which
when coupled with bmap.c/bmap.h/bmap.pal/bmap.pcx do a bumpmapped logo
for cscene.  The graphics and mouse code should help you out immensely =}.


Thanx for reading the doc, have fun with svgalib.
and remember, compile with -lvgagl -lvga!!! IN THAT ORDER!


Id like to state that the views in here are my own, not Nuclear
Winter Entertainment's, or Spheringer Technologies'.

ACK's to:           Greg Alexander (GAlexand on #C) for notifying (Read
                    screaming, kicking ;}) me of the security risk.

Accompanying files: svgatute.tar.gz

Contains:           graphics.c, graphics.h    Header and src for gfx routines
                    mouse.c, mouse.h          Header and src for mouse routines
                    bmap.c, bmap.h, bmap      Header, src, bin for example prog
                    bmap.pal, bmap.pcx        Data files for example prog.

To unpack:          gzip -dc svgatute.tar.gz | tar xvf -
and run:            bmap

C Scene Official Web Site : http://cscene.oftheinter.net
C Scene Un-Official Email : cscene@mindless.com
This page is Copyright © 1997 By C Scene. All Rights Reserved