
 BCC2GRX  -  Interfacing Borland based graphics programs to LIBGRX
 Copyright (C) 1993-96 by Hartmut Schirmer

 This library is copyrighted (see above). It might be used and
 distributed freely as long as all copyright notices are left
 intact.

 You may not distribute any changed versions of BCC2GRX without
 written permission by Hartmut Schirmer.

 You are permitted to distribute an application linked with BCC2GRX
 in binary only, provided that the documentation of the program:

    a)   informs the user that BCC2GRX is used in the program, AND

    b)   provides the user with the necessary information about
	 how to obtain BCC2GRX. (i.e. ftp site, etc..)

 This library is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 Contact :                Hartmut Schirmer
			  Feldstrasse 118
		  D-24105 Kiel
			  Germany

 e-mail : hsc@techfak.uni-kiel.d400.de


1. Introduction and overview
------------------------------------------------------------------------------

   The BCC2GRX was created to allow users of DJGPP/LIBGRX to compile
   graphics programs written for Borland-C++ and Turbo-C graphics
   interface. C code can be directly compiled and linked with BCC2GRX.

   Please note that BCC2GRX was designed for use with the GNU-C compiled
   LIBGRX exclusively (DJGPP and Linux). The Borland-C++ LIBGRX isn't
   supported since one can use the native BGI interface !

   Using DJGPP/LIBGRX or Linux based graphics gives you some advantages :

      - 32 bit linear memory model
      - high efficient C/C++/Objective-C compiler
      - high resolution and high color graphics modes supported
      - easy way to support new graphics adapters
      - Linux, DJGPP, LIBGRX and BCC2GRX are free software
      - most ported applications run faster

   The actual BCC2GRX (v2.0) does only a few error checks since
   it is assumed the progam was extensively tested before porting it
   to DJGPP. BCC2GRX is not a convenient platform to develop new BGI
   programs. Of course you should use DJGPP's native LIBGRX in such
   cases!


2. What do I need to use BCC2GRX ?  Where can I find it ?
------------------------------------------------------------------------------

   There are some things you need to use BCC2GRX :

     DJGPP    DJ Delorie's port ot GNU-C to MS-DOS
     LIBGRX   Csaba Biegl's graphics library for BCC, DJGPP and LINUX
	      (Version 1.03 or 2.x required)
     BCC2GRX  of course

   You can get the DJGPP package from every SimTel mirror. It's
   located in vendors/djgpp.

   You may build three different libraries based on the BCC2GRX package:

    library file | DJGPP  | LIBGRX (build for DJGPP) | included |  Linux
    -------------+--------+--------------------------+----------+--------
    libbcc2.a    |   v2   |       v2.x  (v2)         |    NO    | default
    libbcc.a     |   v1   |       v1.0x (v1)         |    NO    |   ???
    libbccx.a    |   v1   |       v2.x  (v1)         |    NO    |   ---


3a. Installing BCC2GRX for DJGPP-based GRX
------------------------------------------------------------------------------

  1. DJGPP should be installed and fully tested

  2. Install the LIBGRX package and check it. If you're running Linux,
     make sure you know how to set the correct file attributes for
     compiled executables (see svgalib doc).

  3. Install the BCC2GRX and check it :

    a. Unpack bccgrx20.zip in your DJGPP home dir (unzip -o bccgrx20.zip
       or pkunzip -d -o bccgrx20.zip)
    b. Check 'config.dj' in GCC/contrib/bcc2grx for your system
       (NOTE: all makefiles are set up for GNU-make)
    c. If you don't have the required library file (see table above)
       just type 'make clean lib'
    d. type 'make test'.
    e. cd to GCC/contrib/bcc2grx/test and run bccbgi

  4. Set up BCC2GRX for your own programs

    a. Copy GCC/contrib/bcc2grx/lib/libbcc*.a to a directory in your
       LIBRARY_PATH or add GCC/contrib/bcc2grx/lib to LIBRARY_PATH.
    b. Copy GCC/contrib/bcc2grx/include/libbcc.h to a directory in
       your C_INCLUDE_PATH or add GCC/contrib/bcc2grx/include to the
       ???_INCLUDE_PATH environment variables.


  Now BCC2GRX should be installed.

  If you have serious problems, you should notice it on the djgpp
  news group (comp.os.msdos.djgpp) or contact me directly via
  email: hsc@techfak.uni-kiel.d400.de .


3b. Installing BCC2GRX on a Linux system
------------------------------------------------------------------------------

  1. You'll need root permissions to install BCC2GRX !

  2. Make sure you have a working SVGALIB or X11.

  3. Install the LIBGRX package and check it. Make sure you know
     how to set the correct file attributes for executables using svgalib
     (see svgalib doc for details). Check the GRXFONT environment variable!

  4. Install the BCC2GRX and check it :

    a. Unpack bccgrx20.zip in your /tmp dir (unzip -a -L -o bccgrx20.zip)
    b. Move /tmp/contrib/bcc2grx to an apropriate place (eg. /usr/src/bcc2grx)
    c. Check 'config.lnx' in the bcc2grx base dir
    d. build the library and the test programs (make cleanall; make)
    e. Run bcc2grx/test/bccbgi from a terminal console and
	   bcc2grx/test/xbccbgi from X11.

  5. Set up BCC2GRX for your own programs

    a. Copy bcc2grx/lib/libbcc*.a to /usr/local/lib
    b. Copy bcc2grx/include/libbcc.h to /usr/local/include.


  Now BCC2GRX should be installed.


4. Differences between BGI and BCC2GRX
------------------------------------------------------------------------------

   BCC2GRX is based on LIBGRX instead of using an  .bgi driver. This
   introduces some differences compared with the Borland GI. The (known)
   differences are listed below.


   - GNU-C is a 32 bit compiler. An int will take 4 bytes instead of
     2 with Turbo-C and BCC. If you need a 16 bit integer, change
     the definition from int to short witch is 16 bit on either system.
   - WHITE is a function not constant with BCC2GRX. This may cause
     problems in switch () statements.
      (You may use
	 #define WHITE 15
	 #include <libbcc.h>
       to improve compatibility.)
   - BCC2GRX can not use .bgi drivers. Installing an user driver and
     the register(far)bgidriver will always cause an error.
   - registerfarbgifont() and registerbgifont() are the same. Both
     take a void* to the character font (whole file with header !)
   - initgraph()/detectgraph() work slightly different. See below for details.
   - getmodenames() and other functions may be called before initgraph()
   - character files won't be flushed at closegraph()
   - NOT_PUT isn't supported.
   - some constant's may differ in value
   - BCC2GRX's outtext() and outtextxy() do correct clipping
   - some graphics primitives slightly differ in behaviour between BGI
     and LIBGRX. Eg. the "saucer" in bccbgi.c putimage()/getimage() demo
     looks a little different.
   - the BCC2GRX header file is <libbcc.h> . You have to change the
     #include statements since DJGPP defines an incompatible <graphics.h>.
     Conditional compilation is a good way to handle this problem :
	 #ifdef __GNUC__
	 #  include <libbcc.h>
	 #else
	 #  include <graphics.h>
	 #endif


5. Some useful internals of BCC2GRX
------------------------------------------------------------------------------

   Since LIBGRX provides a flexible and powerful set of graphics primitives,
   some of the basic routines are defined within bccgrx.h using "__inline__
   static" functions. GNU-C compiles these functions like macros but you can
   refer to their address. There is one exeption to this rule: When compiling
   code based on a pascal program, a macro is used for getaspectratio since
   the pascal and C graphics interfaces use different calling types.

   BGI has something called a 'viewport'. There are two very different
   behaviors depending on the clipping flag:

     If clipping is on, one introduces something like a subscreen where
     (nearly) all drawing operations are done.
     Otherwise the origin of the drawing coordinate system is shifted from
     the top left corner to some other point on screen.

   BCC2GRX always adds the origin shift to all operations. If clipping is
   requested, GrSetClipBox() is called and LIBGRX restricts drawing to the
   selected subscreen.

   One may wonder why BCC2GRX has it's own drawpoly() function instead
   of using the LIBGRX function. In BGI a polygon isn't really
   a polygon but may be a union of several unconnected closed polygons.
   In more detail:

     If the start point of a polygon is reached again, the next point
     is the start point of a new polyon. No connection line is drawn.

   So one may draw several closed polygons at once. I don't know whether
   this behavior of the BGI is a bug or a feature, but BCC2GRX is
   at least compatible ...


6. initgraph()/detectgraph()/closegraph()
-----------------------------------------------------------------------------

  It's recommented to use something like the following code to
  initialize the graphics interface :

   int gd, gm, err;
   gd = DETECT;                         /* or detectgraph(&gd,&gm); */
   initgraph(&gd,&gm,PATH_TO_CHR_FILES);
   err = graphresult();
   if (err != grOk) ...

  This code sets up the default graphics mode defined in the GO32 or
  GRX20DRV environment variable. This code will work with Borland and
  GRX based BGI code without change. BCC2GRX will treat all gd values as
  'DETECT' and set up the GRX default graphics mode.

  BCC2GRX provides two new functions to select the graphics mode:

      void set_BGI_mode(int *graphdriver, int *graphmode);
  and
      void set_BGI_mode_whc(int *graphdriver, int *graphmode,
			    int width, int height, int colors);

  If your code requires one of the standard BGI modes, use set_BGI_mode()
  with BCC2GRX:

	   gd = VGA; gm = VGAHI;
	 #ifdef __GNUC__
	   set_BGI_mode( &gd, &gm);
	 #endif
	   initgraph( &gd, &gm, "");

  All resolutions including the SVGA modes may be set up by calling
  the set_BGI_mode_whc() function:

	 #ifdef __GNUC__
	   set_BGI_mode_whc( &gd, &gm, 640, 480, 1<<24);
	 #else
	   /* BCC stuff invoking a SVGA mode, needs nonstd BGI driver */
	 #endif
	   initgraph( &gd, &gm, "");


  The BCC2GRX requests the desired resolution from LIBGRX by calling

	GrSetMode( GR_width_height_color_graphics, ...)

  If there is no such mode in the current driver, a related one may be
  set up by LIBGRX. If you program needs a special resolution (say eg.
  Hercules 720x348) you should check getmaxx() and getmaxy() after
  initgraph() .

  Please note that
    - set_BGI_mode(HERCMONO, HERCMONOHI) uses 720x350x16 on VGA cards,
    - all drivers != NATIVE_GRX behave like DETECT with BCC2GRX,
    - set_BGI_mode[_whc]() sets up local variables used by initgraph() and
      setgraphmode(). You may change the resolution after initgraph() done
      by
	     gd = DETECT;
	     initgraph(&gd, &gm, "");
	     /* Default graphics mode */
	     ....
	   #ifdef __GNUC__
	     set_BGI_mode_whc(&gd, &gm, 1024, 768, 256);
	   #else
	     /* BCC stuff to set up 1024x768x256 mode */
	     gm = ... ;
	   #endif
	     setgraphmode( gm);
	     /* Now in 1024x768x256 mode */


  Starting with BCC2GRX v2.0 there are new functions

    getmodemaxcolor(int mode), getmodemaxx(int mode), getmodemaxy(int mode)

  wich may be called at any time, even before initgraph(). A program may
  require true rgb support (32k colors or more) and at least 800x600 pixels.
  The new getmodemax*() functions may be used for flexible setup:

     int gd=DETECT, gm;
   #if defined(__GNUC__) && defined(__BCC2GRX__) && (__BCC2GRX__>=0x200)
     #define XR 800
     #define YR 600
     #define CR (1<<15)
    {int lo,hi,x=0,y=0,c=0,i;
     detectgraph(&gd,&gm);
     getmoderange(gd, &lo, &hi); gm=-1;
     for (i=hi;i>=lo;--i)
       if (getmodemaxcolor(i)>=CR) {
	 if (getmodemaxx(i)==XR && getmodemaxy(i)==YR) {
	   gm = i; /* enough colors and exact geometry */
	   break; /* ==> done */
	 }
	 if (getmodemaxx(i)>=XR && getmodemaxy(i)>=YR)
	   gm = i;
       } else break; /* no success */
     if (gm<0) {puts("Sorry, no sufficent video mode available\n"); exit(1);}}
     #undef XR
     #undef YR
     #undef CR
   #endif
    initgraph(&gd,&gm,"");

  The above example emploits the BCC2GRX ordering of modes:
     less colors first, less total pixel count eariler or
     decide by horizontal width
  Eg.:
     640x480x16  // 16 < 256 available colors
     320x200x256 // 64000 < 128000 total pixel
     640x200x256 // 128000 < 172800 total pixel
     360x480x256 // 360 < 480 horizontal pixel
     480x360x256 // 172800 < 480000 total pixel
     800x600x256 // 256 < 16M available colors
     640x480x16M


  closegraph() doesn't free any allocated memory (eg. vector fonts).


7. Using fonts
------------------------------------------------------------------------------

   The BCC2GRX v1.2 or newer can link vector fonts into the .exe file.
   The standard fonts are in the libbcc*.a :

	   _bold_font, _euro_font, _goth_font, _lcom_font
	   _litt_font, _sans_font, _scri_font, _simp_font
	   _trip_font, _tscr_font

   Call registerbgifont() to enable font usage :

	   registerbgifont( &_bold_font);
	   registerbgifont( &_euro_font);
	   registerbgifont( &_goth_font);
	   registerbgifont( &_lcom_font);
	   registerbgifont( &_litt_font);
	   registerbgifont( &_sans_font);
	   registerbgifont( &_scri_font);
	   registerbgifont( &_simp_font);
	   registerbgifont( &_trip_font);
	   registerbgifont( &_tscr_font);

   Of course you can also link non standard fonts :

	   - copy the .chr file(s) to bcc2grx/src
	   - goto bcc2grx and type 'make'
	   - add
		   extern int _<font_name>_font;
		   registerbgifont( &_<font_name>_font);
	     to your source

   The actual BCC2GRX handels the 11 standard and up to 10 user fonts. If you
   need more user fonts, you should change the definition of LastUserFont in
   text.c !


   Starting with BCC2GRX v1.2 you can also use the LIBGRX bitmapped fonts.
   Just get a font handle and set the new text style. Eg. you may want to
   use the 8x16 VGA font in high resolution graphics:

      font_handle = installuserfont( "pc8x16.fnt");
      settextstyle( font_handle, HORIZ_DIR, 1);

   See test/ttext.c for more examples.

   Please note that GRX 2.x can't scale bitmap fonts at drawing level any
   longer. Before drawing a magnified DEFAULT_FONT, BCC2GRX will first set
   up the required new font and keeps a pointer for later use. Due to this,
   you might notice a slight delay the first time you request a magnified
   font.

   The new GRX 2.x may use Borland vector fonts as native fonts. Managing
   the resulting bitmap fonts would use much more memory than linking the
   font rendering code twice, so I decided not to use the GRX font API.

   Every font will be loaded only once and stay in (virtual) memory until
   the program terminates. If this behaviour doesn't work with your program
   (eg. something like a font editor) or you get short of memory loading
   hundreds of fonts, please tell me about.


8. What's new in this release ?
------------------------------------------------------------------------------

   New copyright terms: copyrighted but free usable, includes commercial usage.
   Updated for GRX 1.03 / .vdr drivers / 64K && 16M color modes
   More robust library internal function naming
   BLACK now is a constant
   Several (minor) bug fixes
   Updated for GRX v2
   libbcc.h won't include GRX and pascal stuff any more
   there's no Pascal support any longer, sorry
   added version control __BCC2GRX__
   Linux support

   For a more complete list of changes and new features check src/changes .
