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

 This library is now part of the GRX graphics library.

 Contact : grx@gnu.de

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

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

  Using LIBGRX based graphics gives you some advantages :

     - 32 bit linear memory model (except for Turbo-C and BCC / DOS)
     - high resolution and high color graphics modes supported
     - easy way to support new graphics adapters
     - 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 GRX.
  BCC2GRX is not a convenient platform to develop new BGI programs. Of
  course you should use 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.

     - Most LIBGRX platforms are 32 bit. An int will take 4 bytes instead of
       2 with Turbo-C and BCC for DOS. If you need a 16 bit integer, change
       the definition from int to short which is 16 bit on all systems.
     - 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 must change the #include
       statements since BCC2GRX is incompatible with <graphics.h>. For
       programs compatible with both Borland GI and BCC2GRX, conditional
       compilation may be used:
         #if defined(__MSDOS__) && defined(__TURBOC__)
         #  include <graphics.h>
         #else
         #  include <libbcc.h>
         #endif
       and such programs should be linked with the respective library,
       either Borland or GRX (but not both).
     - 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 when using a GNU-C compiler. It compiles these functions
  like macros, but you can refer to their addresses. 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 */
           ....
         #if defined(__TURBOC__) && defined(__MSDOS__)
           /* Borland GI stuff to set up 1024x768x256 mode */
           gm = ... ;
         #else
           set_BGI_mode_whc(&gd, &gm, 1024, 768, 256);
         #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(__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.


9. LIBGRX 2.4.5 and later
-----------------------------------------------------------------------------

  Starting with LIBGRX 2.4.5, BCC2GRX supports Turbo-C and BCC. The
  documentation has been updated accordingly.
