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

 This library is now part of the GRX graphics library.

 Contact :                Hartmut Schirmer
			  Feldstrasse 118
		  D-24105 Kiel
			  Germany

 e-mail : hsc@techfak.uni-kiel.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 current BCC2GRX (v2.3) does only a few error checks since
   it is assumed the program 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. 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 constants 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
   - the color constants like REG, GREEN, etc. won't work in graphics
     modes with more than 256 colors. Use
       _ega_color(RED), _ega_color(GREEN), etc
     to get the right colors


3. 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 polygon. 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 ...


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

  It's recommended 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)

  which 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 sufficient video mode available\n"); exit(1);}}
     #undef XR
     #undef YR
     #undef CR
   #endif
    initgraph(&gd,&gm,"");

  The above example exploits the BCC2GRX ordering of modes:
     less colors first, less total pixel count earlier 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).

  The paging routines setactivepage() and setvisualpage() are functional
  for GRX v2 base BCC2GRX. Just call set_BGI_mode_pages() before calling
  initgraph():

     set_BGI_mode_pages(2);  /* 1 or 2 valid ! */
     initgraph(...);
     if (graphresult() == grOk && get_BGI_mode_pages() > 1) {
       /* Do cool paging stuff */
     }

  You can't check paging without switching into graphics mode!
  Translating BCC modes by set_BGI_mode() will disable paging!


5. 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: same license as the rest of GRX.
   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 stuff any more
   added version control __BCC2GRX__
   Linux support
   setactivepage()/setvisualpage() with GRX v2

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