PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 1/12 TITLE : Common issues about BGI graphics. WHAT IS BGIOBJ? =============== BGIOBJ.EXE is a conversion utility for graphics drivers and fonts. You can use BGIOBJ to convert graphic driver files (.BGI) and character sets (.CHR) files to object (.OBJ) files. Once the driver and font files have been converted to .OBJ files, they can be linked into your program making them part of the executable, as opposed to the dynamic loading scheme in which your program loads graphics drivers and fonts from disk at run time. Certain trade-offs exist between the linking scheme versus the dynamic loading scheme. Linking the drivers and fonts into the executable can be very advantageous and convenient, however, it also increases the executable file size. When executable size becomes a factor, the programmer may wish to use dynamic loading from disk instead. (See DYNAMIC LOADING OF DRIVERS AND FONTS). USING TLIB.EXE ============== TLIB.EXE is documented in the Tools and Utilities Guide or in your UTIL.DOC file located in borlandc\doc subdirectory. When using tlib, it is always best to get a listing file to confirm the symbols that are placed in the library. This is a very powerful tool to use when getting any undefined symbol or similiar errors. Example: ' tlib graphics.lib, listing ' will yield a listing.lst file you can view for public symbols. USING BGIOBJ.EXE ================ 1. BGIOBJ FOR BORLAND'S .BGI AND .CHR FILES: ============================================= 1) Invoke bgiobj with the desired .bgi or .chr file, For Example, in the borlandc\bgi directory type: 'bgiobj gothic'. PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 2/12 TITLE : Common issues about BGI graphics. 2) Add gothic.obj to graphics.lib, In the borlandc\lib directory type: 'tlib graphics.lib +d:\borlandc\bgi\gothic.obj,listing' Note: It is important to run tlib in the directory where graphics.lib is located. To verify the correct addition, view the listing file named listing.lst. Once you have added the .obj files to graphics.lib, you must make a call to a registering routine. How registerbgidriver() and registerbgifont() work: These functions enable the user to load a driver/font file and "register" it. The function takes an function prototype symbol name as an argument, as defined in graphics.h. In the following example, the function symbol is sansserif_font as defined in graphics.h. Note: Function prototypes have not been defined for all the .chr files that are provided in the \borlandc\bgi subdirectory. To see which function prototypes have been provided, look in the graphics.h file under graphics fonts. /**********************************************************/ /* Example registering bgi fonts and adding to executable */ #include #include #include #include int main(void) { int gdriver = DETECT, gmode, errorcode; int midx, midy, size; errorcode = registerbgifont(sansserif_font); if (errorcode < 0) { /* an error occured */ printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 3/12 TITLE : Common issues about BGI graphics. getch(); exit(1); /* terminate with an error code */ } /* initialize graphics and local variables */ initgraph(&gdriver, &gmode, "d:\\bc31\\bgi"); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) { /* an error occured */ printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); /* terminate with an error code */ } midx = getmaxx() / 2; midy = getmaxy() / 2; size = 4; settextjustify(CENTER_TEXT, CENTER_TEXT); settextstyle(SANS_SERIF_FONT, HORIZ_DIR, size); outtextxy(midx, midy, "SANSSERIF"); getch(); /*clean up*/ closegraph(); return 0; } 2. BGIOBJ FOR 3RD PARTY .BGI AND .CHR FILES: ============================================= When you invoke BGIOBJ.EXE for 3rd party drivers and/or fonts you must supply all parameters. (See UTIL.DOC in the \doc subdirectory). 1) In the borlandc\bgi directory type: PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 4/12 TITLE : Common issues about BGI graphics. 'bgiobj myfont.bgi myfont.obj _myfont' _myfont is the public name used in your call to registerbgifont,the public name is the external name used by the linker, thus the need for the leading underscore. Example: registerbgifont(myfont); 2) Make sure to add the prototype for the function you pass to the registering function. We suggest that instead of directly modifying the graphics.h file, that you create your own header file containing the prototype. Example: #ifdef __cplusplus extern "C" { #endif /*put new function prototypes here*/ void cdecl my_driver(void); #ifdef __cplusplus } #endif 3) Make call to installuserdriver(), this adds 3rd party devices to BGI internal table. 4) Make call to register function: either registerbgidriver(), or registerbgifont(). 5) Pass the return value from installuserdriver() to initgraph. /******************************************************/ /* Example of registering 3rd party fonts/drivers and */ /* adding to exe */ #include #include #include #include /*Add prototype for function to be passed to the registering function, should be defined in your own header file. */ PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 5/12 TITLE : Common issues about BGI graphics. #ifdef __cplusplus extern "C" { #endif void cdecl vga256(void); #ifdef __cplusplus } #endif int huge alwaysZero() { return 0; } void checkErrors() { int errorcode; errorcode = graphresult(); if (errorcode != grOk) { /* an error occured */ printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); /* terminate with an error code */ } } int main(void) { int gdriver, gmode, errorcode; gdriver = installuserdriver("vga256", alwaysZero); checkErrors(); registerbgidriver(vga256); checkErrors(); /* initialize graphics and local variables */ initgraph(&gdriver, &gmode, "d:\\bc31\\bgi"); checkErrors(); PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 6/12 TITLE : Common issues about BGI graphics. setcolor(WHITE); line(0, 0, getmaxx(), getmaxy()); /* clean up */ getch(); closegraph(); return 0; } 3. LINKING IN FAR SEGMENTS WITH BGIOBJ: ======================================== If you get a linker error _TEXT EXCEEDS 64K after linking in drivers or fonts using registerbgidriver(), and you still wish to incorporate the drivers into your executable with either of the registering routines (registerbgidriver/registerbgifont), do the following: Use BGIOBJ with the /F option. Example: type the following in the borlandc\bgi subdirectory: 'bgiobj /F egavga' This options directs BGIOBJ to use a segment name of the form filename_TEXT versus _TEXT, in the above example it would be egavga_TEXT. (See UTIL.DOC for further discussion). BGIOBJ with the /F paramater appends F to the target object file name, (egavgaf.obj), and appends _far to the symbol name that serves as the function prototype, (EGAVGA_driver_far). In addition, you must use the far registering routines instead of the the normal registerbgidriver(). Example: if (registerfarbgidriver(EGAVGA_driver_far) < 0) exit(1); if (registerfarbgifont(EGAVGA_font_far) < 0) exit(1); PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 7/12 TITLE : Common issues about BGI graphics. 4. USING BGIOBJ /F WITH THIRD PARTY DRIVERS AND FONTS: ======================================================= 1) Make sure to supply all the necessary parameters, including explicitly adding the appended f for the .obj file and the appended _far to the symbol. Example: 'bgiobj /F myfont.bgi myfontf.obj _myfont_far' 2) When adding the prototype for the function, we recommend that you create your own header file, Example: #ifdef __cplusplus extern "C" { #endif /*place your new prototypes here*/ extern int far _cdecl myfont_far[]; #ifdef __cplusplus } #endif 5. DYNAMIC LOADING OF DRIVERS OR FONTS ======================================= Make sure that you have access to the correct driver and/or font files on disk. Example: 'initgraph(&gdriver, &gmode, "d:\\borlandc\\bgi")' (Upon which d:\borlandc\bgi is the directory the .bgi or .chr file is located.) /*****************************************************/ /* In the following example all .chr files and the */ /* correct .bgi file are located on b:\bgi where */ /* they are dynamically loaded from disk */ /*****************************************************/ #include #include #include #include PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 8/12 TITLE : Common issues about BGI graphics. int main(void) { int gdriver = DETECT, gmode, errorcode; int midx, midy; int style; /* initialize graphics and local variables */ /* The font files are located on b:\bgi */ initgraph(&gdriver, &gmode, "b:\\bgi"); /* read result of initialization */ errorcode = graphresult(); if (errorcode != grOk) { /* an error occured */ printf("Graphics error: %s\n", grapherrormsg(errorcode)); printf("Press any key to halt:"); getch(); exit(1); /* terminate with an error code */ } midx = getmaxx() / 2; midy = getmaxy() / 2; settextjustify(CENTER_TEXT, CENTER_TEXT); for (style=DEFAULT_FONT; style<=BOLD_FONT; style++) { cleardevice(); settextstyle(style, HORIZ_DIR, 4); outtextxy(midx,midy,"NEW FONT"); getch(); } /* clean up */ getch(); closegraph(); return 0; } BGI COMMON QUESTIONS AND ANSWERS ================================ PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 9/12 TITLE : Common issues about BGI graphics. Q: My graphics program compiles but does not link. I am getting undefined symbols for the BGI functions. Why? A: In the IDE, turn on the Graphics Library in Options|Linker|Libraries. On the command line, link in the graphics library by either putting graphics.lib on the bcc or tlink line. Q: When I run bgiobj with my font or driver file, I get the following error: "Please correct or specify full source filename and public name". A: BGIOBJ does not want the filename extension for Borland C++ provided.bgi or .chr files. Instead invoke like: 'bgiobj egavga' without the file extension. Q: When I run my BGI program I get "Graphics error: Device driver not found", what is wrong? A: Either one of two things has happened: 1) If you are using the dynamic loading feature of BGI: The third parameter to initgraph is the path to the driver. This path is used for dynamic loading of the drivers and/or fonts. Typically the path to the drivers is \borlandc\bgi. Remember that the back-slash character ('\') is special in C. You will need two back-slash characters for each back- slash in the path. For example: initgraph(&gdriver,&gmode,"c:\\borlandc\\bgi"); 2) If you are not using the dynamic feature of BGI: You must use BGIOBJ.EXE to create an .OBJ file, add it to graphics.lib, and make a call to registerbgidriver() or registerbgifont(). In addition, if this is a 3rd party driver or font, you must also make a call to installuserdriver() or installuserfont(). (See USING BGIOBJ.EXE). Q: When I run my BGI program, I get the following error: "BGI Error: graphics not initialized (use 'initgraph')" PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 10/12 TITLE : Common issues about BGI graphics. A: For some reason initgraph failed. To find out why, check the return value of graphresult(), the error code is enumerated in graphics.h. Example: int errorcode; int gdriver = DETECT, gmode; initgraph(&gdriver, &gmode, "d:\\borlandc\\bgi"); if ((errorcode = graphresult() ) != grOk) { printf ("Error : %s\n", grapherrormsg(errorcode)); exit (1); }; Q: When I compile by BGI program, I get a linker error: "Linker Error: Undefined symbol _EGAVGA_driver" A: The linker was unable to locate the public name for your driver. If you are using registerbgidriver() to include the graphics driver at link time, you must be sure to include the library that contains the symbol by checking the following: 1) Make sure that your library path points to the current directory where graphics.lib is located. (Example: Under Options|Directories "d:\borlandc\lib"). 2) Make sure that graphics.lib contains the symbol the linker is complaining about. You can do this by running tlib to get a listing of the symbols in the library. (Example: at the following prompt 'd:\borlandc\lib>' type "tlib graphics.lib, graph". This will create a graph.lst text file you can view for the symbol.) 3) If the library does not contain the symbol, you must add the object file to the library. You can do this by running tlib from the directory where graphics.lib is located. (Example: at the following prompt 'd:\borlandc\lib>' type "tlib graphics.lib +d:\borlandc\bgi\egavga.obj"). Q: Why can't I get 256 colors using BGI? PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 11/12 TITLE : Common issues about BGI graphics. A: The drivers provided with the package do not support a VGA 256 color mode. These can be obtained from 3rd party vendors or can be created using the BGI Toolkit which is provided free on the Borland BBS and other online services such as CompuServe, Genie or BIX. The toolkit contains a 320x200 256 color driver. Q: Why does my SVGA monitor switch to VGA mode when I run my graphics program? A: The drivers provided with the package do not support SVGA. These can also be obtained from 3rd party vendors or can be created using the BGI Toolkit. (See above) Q: When I compile my BGI program, I get linker error: "Segment exceeds 64k" A: This happens commonly in Small and Compact memory models. By default the files created by BGIOBJ.EXE all use the same segment (called _TEXT). This can cause problems if you program links in many drivers and/or fonts. To solve this problem, convert one of more of the drivers or fonts with the BGIOBJ /F option. This option directs BGIOBJ to use a segment name of the form filename_TEXT. This frees up space in the default _TEXT segment. (See LINKING IN FAR SEGMENTS). Q: I have an IBM8514 graphics card, and whenever I use DETECT or detectgraph() with my program, it thinks that I have a VGA card. How can I get it tod etect that I have an IBM8514? A: In order for BGI to recognize the IBM8514 card, you must do the following: IBM provides software interface for this card called hdiload.com. You must first load hdiload.com. Secondly, you must explicitly call initgraph with the correct driver for the 8514. (See graphics.h for enumeration value to send initgraph). Q: I make a call to registerbgifont(some_font) and I get an "UNDEFINED SYMBOL ERROR" PRODUCT : Borland C++ NUMBER : 1292 VERSION : All OS : DOS DATE : October 25, 1993 PAGE : 12/12 TITLE : Common issues about BGI graphics. A: Either one of two things has happened: Either you are not referring to the function prototype for the font as it is defined, or the function prototype isn't defined at all. Check in graphics.h for the prototype definition under either graphics fonts or graphics drivers. Q: Can I use BGI functions in Windows? A: No, BGI functions are not supported in Windows. DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.