home *** CD-ROM | disk | FTP | other *** search
- /*
- demograb.c
-
- C-scape 3.2 Example Program
- Copyright (c) 1990 by Oakland Group, Inc.
- ALL RIGHTS RESERVED.
-
- This program demonstrates how graphics images can be drawn
- on top of C-scape screens and then saved into the window for mobility.
-
- This program relies on the compiler supplied graphics library
- to draw the graphic images.
-
- The following graphics libraries are supported:
-
- Note: If you are running on a CGA then you must run
- the DOS utility GRAPTABL.COM before running
- this program. GRAPTABL.COM loads the extended
- ASCII character set for use in graphics mode.
-
- Note: The Microsoft 5.1 graphics library does not support the
- Hercules card. The Microsoft 6.0 library does, but first
- you have to install a TSR utility for it to work.
-
- Revision History:
- -----------------
- 1/31/90 jmd added environment variable support
- 4/01/90 jmd ansi-fied
- 4/22/90 pmcm added check on fexit before updating graph
- 6/06/90 jmd changed main to return an int
- 9/14/90 bkd changed to use exit(0) instead of return(0).
- 10/19/90 pmcm included ostdlib.h for exit(), added return(1)
- 10/31/90 jmd added call to DoSexit
- 11/02/90 ted added m6, tc++ support.
- 12/01/90 ted added (int) casts in fg_color & bardata[i] assignments.
- 12/01/90 ted prototyped main, except if Turbo C++.
- 12/01/90 ted removed unused 'box' variable in MS dgraf_Init.
- 12/04/90 ted restored "" includes for C-scape headers (not <> includes).
- 12/08/90 pmcm removed reference in note section re: defining M5
- */
-
- #include <stdio.h>
-
- #include "cscape.h"
- #include "olimits.h" /* we need this for prompting user of MAXINT */
- #include "ostdlib.h"
- #include "pcmode.h"
- #include "pmwinobj.h" /* for pmwin stuff */
- #include "scancode.h"
-
-
- /*** Conditionally include compiler-supplied graphics library header ***/
-
- /*----------------------------- Microsoft C specific ---------------------*/
-
- #ifdef M6
- #include <graph.h>
- #endif
-
- /*----------------------------- Borland Turbo C specific -----------------*/
-
- #ifdef __TURBOC__
- #include <graphics.h>
-
- /*
- Borland Users!
- BGI_PATH is directory in which initgraph looks for the
- Borland .BGI files. You may have to change this path
- depending on how you have installed your Turbo C compiler.
- Consult the Turbo C manual under initgraph for more information.
- Note that the backslashes in the path name must quoted
- with a preceding backslash.
-
- You can also define the environment variable BGIPATH
- which overrides this #define:
-
- set BGIPATH=\tc\bgi
- */
-
- #define BGI_PATH "\\TC\\"
-
- #endif
-
- /*----------------------------- End of Compiler specific section -------------*/
-
-
-
- /*** data structure to hold information about the demo ***/
-
- typedef struct {
- int hgt; /* display height in pixels */
- int wid; /* display width in pixels */
- int ncolors; /* number of available colors */
-
- byte reg; /* colors used by menus and popups */
- byte sel;
-
- } dgraf_struct;
-
-
- /*** Macros and definitions ***/
-
- #define nrand(n) (rand() % (n))
- #define QUIT 999
-
- /*** Function prototypes ***/
-
- /* Turbo C++ complains if main is prototyped */
- #ifndef TCP
- int main(void);
- #endif
-
- sed_type makesed(int *bardata);
- boolean spc_UpdateGraph(sed_type sed, int scancode);
- void UpdateGraph(win_type win);
-
- /* graphics routines */
-
- int dgraf_Init(dgraf_struct *dgrafp);
- void dgraf_Line(opbox *opboxp, int color);
- void dgraf_Rectangle(opbox *opboxp, int color);
- void dgraf_FillRectangle(opbox *opboxp, int color);
- void dgraf_Clear(void);
-
- #define BAR_COUNT 5
-
- /* global data */
-
- sed_type mainsed = NULL;
- win_type graphwin = NULL;
-
- int bardata[BAR_COUNT];
-
- int fg_color, bg_color;
- /*----------------------------- MAIN -----------------------------------------*/
-
- int main(void)
- {
- dgraf_struct dgraf;
- int i, x;
- ocbox cbox;
- pmap_type pmap;
-
-
- /*
- Initialize the C-scape device interface:
- def_ModeGraphics selects best available graphics mode
- */
-
- if (!disp_Init(def_ModeGraphics, FNULL)) {
- printf("\nDEMOGRAB: -- No graphics hardware found;");
- printf("\n -- Or, insufficient memory to initialize the OWL ...");
- printf("\n (This program requires a large memory mode)\n");
- exit(1);
- return(1);
- }
-
- /* map colors for 2 color video modes */
- if (disp_GetColors() <= 2L) {
- disp_MapMono(TRUE);
- fg_color = 1;
- bg_color = 0;
- }
- else {
- fg_color = (int) disp_GetColors() - 1;
- bg_color = 3;
- }
-
- /* Initialize Graphics Library */
- if ((x = dgraf_Init(&dgraf)) != 0) {
- disp_Close();
-
- #ifdef __TURBOC__ /* Turbo C */
- switch(x) {
- case -2:
- printf("\nDEMOGRAB: Turbo C initgraph cannot detect graphics card.\n");
- break;
- case -3:
- printf("\nDEMOGRAB: Turbo C initgraph cannot find BGI driver file.\n");
- break;
- case -4:
- printf("\nDEMOGRAB: Turbo C initgraph does not support this video hardware.\n");
- break;
- case -5:
- printf("\nDEMOGRAB: Turbo C initgraph insufficient memory to load driver.\n");
- break;
- default:
- printf("\nDEMOGRAB: Turbo C initgraph error %d.\n", x);
- break;
- }
- #else
- printf("\nDEMOGRAB: Microsoft C _setvideomode does not support this video hardware.\n");
- #endif
-
- exit(1);
- return(1);
- }
-
- /* Turn on the mouse */
- hard_InitMouse();
-
- /* Turn on sedwin mouse */
- sedwin_ClassInit();
-
- /* Turn on pmap window mouse */
- pmwin_MouseInit();
-
- /* initialize bar data */
- for (i = 0; i < BAR_COUNT; i++) {
- bardata[i] = (int) (((float) rand() / (float) RAND_MAX) * (float) 100) + 1;
- }
-
- /* create the main sed */
- mainsed = makesed(bardata);
-
- /* create the graphwin:
- * the graphwin is a pmwin (pixel map window) to which we draw the
- * graphic. We then affix the graphic to the window by calling
- * win_Grab(win)
- */
-
- /* first define the size of the windows in a ocbox structure: */
- cbox.toprow = 10;
- cbox.leftcol = 30;
- cbox.botrow = 20;
- cbox.rightcol = 70;
-
- /*
- now create the window with win_Open. We pass win_Open
- the class function for the type of window we wish to create,
- in this case pmwin_Class, and a pointer to the ocbox structure
- defining its initial size and position.
- */
-
- graphwin = win_Open(pmwin_Class, &cbox);
-
- win_SetAttr(graphwin, 0x3f);
- win_SetBorder(graphwin, bd_1);
- win_SetShadow(graphwin, 1);
-
- bord_SetFeature(graphwin, BD_MOVE);
-
- /* create a pmap, clear it, and connect it to the pmwin */
- pmap = pmap_Open(win_GetPixWidth(graphwin), win_GetPixHeight(graphwin));
- pmap_Clear(pmap, 0);
- pmwin_SetPmap(graphwin, pmap);
-
- win_Employ(graphwin);
- UpdateGraph(graphwin);
-
- /* activate the main sed */
- sed_Go(mainsed);
-
- win_Close(graphwin);
-
- /* the pmap must be closed specifically, it is not automatically
- * closed by win_Close
- */
- pmap_Close(pmap);
-
- sed_Close(mainsed);
-
- /* close down device interface */
- disp_Close();
-
- exit(0);
- return(0);
- }
-
- sed_type makesed(int *bardata)
- /*
- Create a sed for entering bar data.
-
- bardata is array of BAR_COUNT integers. As the values in bardata
- are changed the graph in graphwin is updated.
- */
- {
- menu_type menu;
- sed_type sed;
- int i;
-
- static char intmax_prompt[80];
-
- sprintf(intmax_prompt, " Enter a number 0 to %-d ", INT_MAX);
-
- menu = menu_Open();
-
- for (i = 0; i < BAR_COUNT; i++) {
- menu_Printf(menu, "@p[%d,3]Bar data %2d: @fd[#####]", i, i,
- &bardata[i], &pint_funcs, intmax_prompt);
- }
-
- menu_Printf(menu, "\n\n @p[3]@f[ All Done ]", NULL, &menu_funcs);
-
- menu_Flush(menu);
-
- sed = sed_Open(menu);
- sed_SetColors(sed, 0x1e, 0x17, 0x40);
-
- sed_SetBorder(sed, bd_prompt);
- sed_SetBorderFeature(sed, BD_MOVE);
-
- sed_SetBorderColor(sed, 0x1b);
- sed_SetBorderTitle(sed, "demograb");
- sed_SetPosition(sed, 1, 1);
- sed_SetHeight(sed, 10);
- sed_SetWidth(sed, 39);
- sed_SetShadow(sed, 1);
- sed_SetShadowAttr(sed, 0x08);
-
- sed_SetMouse(sed, sedmou_Track);
- sed_SetSpecial(sed, spc_UpdateGraph);
-
- sed_Repaint(sed);
-
- return(sed);
- }
-
- boolean spc_UpdateGraph(sed_type sed, int scancode)
- /*
- Updates the graph when a field is changed.
- Assumes graph windows is stored in global variable, 'graphwin'.
- */
- {
- static int savedata[BAR_COUNT];
- boolean mustRebuild = FALSE;
- int i;
-
- /* If we changed fields, update the graph */
- switch (scancode) {
- case ESC:
- case ENTER:
- case UP:
- case DOWN:
- case PGUP:
- case PGDN:
- /* we are going to change fields,
- * call field fexit to test if field is valid.
- * if valid, test if we need to update the graph
- */
-
- if (sed_DoFieldFexit(sed, sed_GetFieldNo(sed))) {
- /*
- * Move field record into variable.
- * Call the sexit function.
- * The sexit writes the string of digits in the field
- * record to the native field variable.
- */
- sed_DoFieldSexit(sed, sed_GetFieldNo(sed));
-
- for (i = 0; i < BAR_COUNT; i++) {
- if (bardata[i] != savedata[i]) {
- savedata[i] = bardata[i];
- mustRebuild = TRUE;
- }
- }
- if (mustRebuild) {
- UpdateGraph(graphwin);
- }
- }
-
- break;
- }
-
- return(FALSE);
- }
-
- void UpdateGraph(win_type win)
- /*
- Repaint the graph to the display directly
- then copy the graphics from the display to the graph window's
- pmap with win_Grab().
- */
- {
- opcoord winx, winy;
- odim hight, width;
- opbox pbox;
- int i, maxbar, ymargin, xmargin, barwidth;
- double scale;
-
- /* get location and size of window (in pixels) */
- winx = win_GetXmin(win);
- winy = win_GetYmin(win);
-
- hight = win_GetPixHeight(win);
- width = win_GetPixWidth(win);
-
- ymargin = hight / 10;
- xmargin = width / 10;
-
- barwidth = (width - xmargin * 2) / (BAR_COUNT);
-
- /* temporarily turn off mouse cursor,
- * so that we don't draw over it.
- * note: disp_Cache must be followed by a call to disp_Flush.
- */
- disp_Cache();
-
- /* first, clear the region */
- pbox.xmin = winx;
- pbox.xmax = winx + width;
- pbox.ymin = winy;
- pbox.ymax = winy + hight;
- dgraf_FillRectangle(&pbox, bg_color);
-
- /* draw y axis */
- pbox.xmin = pbox.xmax = winx + xmargin;
- pbox.ymin = winy + ymargin;
- pbox.ymax = winy + hight - ymargin;
- dgraf_Line(&pbox, fg_color);
-
- /* draw x axis */
- /* pbox.xmin and pbox.ymax stay the same */
- pbox.xmax = winx + width - xmargin;
- pbox.ymin = pbox.ymax;
- dgraf_Line(&pbox, fg_color);
-
- /* find the largest bar (for auto scale) */
- maxbar = bardata[0];
- for (i = 1; i < BAR_COUNT; i++) {
- if (bardata[i] > maxbar) {
- maxbar = bardata[i];
- }
- }
- scale = (.8 * hight) / (float) (maxbar ? maxbar : 1);
- /* draw bars */
- for (i = 0; i < BAR_COUNT; i++) {
-
- pbox.xmin = winx + xmargin + (barwidth * i) + barwidth / 4;
- pbox.xmax = pbox.xmin + (barwidth * 3) / 4;
- pbox.ymax = winy + hight - ymargin - 1;
- pbox.ymin = pbox.ymax - (int) ((double) bardata[i] * scale);
- dgraf_FillRectangle(&pbox, fg_color);
- }
-
- /* turn mouse cursor back on,
- * note: disp_Flush must be preceeded by a call to disp_Cache.
- */
- disp_Flush();
-
- /* now copy the picture in to the pmwin */
- win_Grab(win);
- }
-
-
- /*---------------------------------------------------------------------------*/
-
- /*
- Portable graphics routines:
- The following routines are defined for the various graphics libraries
- supported.
- */
-
- /*----------------------------- Microsoft C specific ---------------------*/
-
- #ifdef M6 /* Microsoft */
-
- int dgraf_Init(dgraf_struct *dgrafp)
- /*
- Microsoft version.
-
- Initialize the graphics library.
- Initialize demo data.
-
- Returns
- 0 if successful
- -1 if the video hardware is unsupported by MS.
-
- */
-
- {
- struct videoconfig config; /* Microsoft defined structure */
- short mode;
-
- switch(pc_GetMode()) {
-
- case 0x13:
- mode = _MRES256COLOR;
- break;
-
- case 0x12:
- mode = _VRES16COLOR;
- break;
-
- case 0x11:
- mode = _VRES2COLOR;
- break;
-
- case 0x10:
- mode = _ERESCOLOR;
- break;
-
- case 0x0f:
- mode = _ERESNOCOLOR;
- break;
-
- case 0x0e:
- mode = _HRES16COLOR;
- break;
-
- case 0x0d:
- mode = _MRES16COLOR;
- break;
-
- case 0x06:
- mode = _HRESBW;
- break;
-
- case 0x05:
- case 0x04:
- mode = _MRESNOCOLOR;
- break;
-
- case 0x10A:
- case 0x10B:
- /*
- The Hercules graphics card is not supported by Microsoft 5.1. _HERCMONO
- is in their graphic.h but does not work with _setvideomode, below.
- */
- mode = _HERCMONO;
- break;
-
- case 0x140:
- /* Compaq Plasma 40 not supported by Microsoft, fall through ... */
-
- default:
- return(-1);
- }
-
- /* initialize Microsoft video mode */
- if ((_setvideomode(mode)) == 0) {
- return(-1); /* unsupported hardware configuration */
- }
-
- /* initialize config structure */
- _getvideoconfig(&config);
-
- dgraf_Clear();
-
- /* set up dgraf data */
-
- dgrafp->hgt = config.numypixels;
- dgrafp->wid = config.numxpixels;
- dgrafp->ncolors = config.numcolors;
-
- /* Set up the menu colors */
- if (disp_GetColors() > 2L) {
- dgrafp->reg = 0x34;
- dgrafp->sel = 0x43;
- }
- else {
- dgrafp->reg = 0x10;
- dgrafp->sel = 0x01;
- }
-
- return(0);
- }
-
- void dgraf_Line(opbox *opboxp, int color)
- /*
- Draw a line from
- (opboxp->xmin, opboxp->ymax) to (opboxp->xmax, opboxp->ymax)
- with color color.
-
- Microsoft version.
- */
- {
- _setcolor(color);
- _moveto(opboxp->xmin, opboxp->ymin);
- _lineto(opboxp->xmax, opboxp->ymax);
- }
-
- void dgraf_Rectangle(opbox *opboxp, int color)
- /*
- Draw a rectangle with corners
- (opboxp->xmin, opboxp->ymax) (opboxp->xmax, opboxp->ymax)
- with color color.
-
- Microsoft version.
- */
- {
- _setcolor(color);
- _rectangle(_GBORDER, opboxp->xmin, opboxp->ymin, opboxp->xmax, opboxp->ymax);
- }
-
- void dgraf_FillRectangle(opbox *opboxp, int color)
- /*
- Draw a filled rectangle with corners
- (opboxp->xmin, opboxp->ymax) (opboxp->xmax, opboxp->ymax)
- with color color.
-
- Microsoft version.
- */
- {
- _setcolor(color);
- _rectangle(_GFILLINTERIOR, opboxp->xmin, opboxp->ymin, opboxp->xmax, opboxp->ymax);
- }
-
- void dgraf_Clear()
- /*
- Clear the display.
-
- Microsoft version.
- */
- {
- _clearscreen(_GVIEWPORT);
- }
-
- #endif
-
- /*----------------------------- Borland Turbo C specific -----------------*/
-
-
- #ifdef __TURBOC__ /* Turbo C */
-
- int dgraf_Init(dgraf_struct *dgrafp)
- /*
- Turbo C version.
-
- Initialize the graphics library.
- Initialize demo data.
-
- Returns
- 0 if successful.
-
- turbo initgraph error code if not successful:
- -2 cannot detect graphics card
- -3 cannot find driver file
- -4 invalid driver (unsupported video mode)
- -5 insufficient memory to load driver
-
- */
- {
- int mode, driver;
- char *bgipath;
-
- switch(pc_GetMode()) {
-
- case 0x12:
- driver = VGA;
- mode = VGAHI;
- break;
-
- case 0x11:
- driver = MCGA;
- mode = MCGAHI;
- break;
-
- case 0x10:
- driver = EGA;
- mode = EGAHI;
- break;
-
- case 0x0f:
- driver = EGAMONO;
- mode = EGAMONOHI;
- break;
-
- case 0x0e:
- driver = EGA;
- mode = EGALO;
- break;
-
- case 0x06:
- driver = CGA;
- mode = CGAHI;
- break;
-
- case 0x05:
- case 0x04:
- driver = CGA;
- mode = CGAC1;
- break;
-
- case 0x10A:
- case 0x10B:
- driver = HERCMONO;
- mode = HERCMONOHI;
- break;
-
- case 0x140: /* Compaq plasma mode 40 */
- driver = ATT400;
- mode = ATT400HI;
- break;
-
- case 0x13: /* 320x200 (pc_Mode13) 256 color VGA/MCGA, fall through... */
-
- case 0x0d: /* 320x200 (pc_ModeD) 16 color EGA, fall through... */
-
- default:
- /* Not supported by TC -- return code for invalid driver */
- return(-4);
- }
-
- /* test for environment variable */
- if ((bgipath = getenv("BGIPATH")) == NULL) {
- bgipath = BGI_PATH;
- }
-
- initgraph(&driver, &mode, bgipath);
-
- if (driver < 0) {
- /* initgraph failed */
- return(driver);
- }
-
- dgraf_Clear();
-
- /* set up dgraf data */
-
- dgrafp->hgt = getmaxy();
- dgrafp->wid = getmaxx();
- dgrafp->ncolors = getmaxcolor() + 1;
-
- /* Set up the menu colors */
- if (disp_GetColors() > 2L) {
- dgrafp->reg = 0x34;
- dgrafp->sel = 0x43;
- }
- else {
- dgrafp->reg = 0x10;
- dgrafp->sel = 0x01;
- }
-
- return(0);
- }
-
- void dgraf_Line(opbox *opboxp, int color)
- /*
- Draw a line from
- (opboxp->xmin, opboxp->ymax) to (opboxp->xmax, opboxp->ymax)
- with color color.
-
- Turbo C version.
- */
- {
- setcolor(color);
- /* setlinestyle(SOLID_LINE, 0, THICK_WIDTH); */
-
- line(opboxp->xmin, opboxp->ymin,
- opboxp->xmax, opboxp->ymax);
- }
-
- void dgraf_Rectangle(opbox *opboxp, int color)
- /*
- Draw a rectangle with corners
- (opboxp->xmin, opboxp->ymax) (opboxp->xmax, opboxp->ymax)
- with color color.
-
- Turbo C version.
- */
- {
- setcolor(color);
- rectangle(opboxp->xmin, opboxp->ymin,
- opboxp->xmax, opboxp->ymax);
- }
-
- void dgraf_FillRectangle(opbox *opboxp, int color)
- /*
- Draw a filled rectangle with corners
- (opboxp->xmin, opboxp->ymax) (opboxp->xmax, opboxp->ymax)
- with color color.
-
- Turbo C version.
- */
- {
- setfillstyle(SOLID_FILL, color);
- bar(opboxp->xmin, opboxp->ymin,
- opboxp->xmax, opboxp->ymax);
- }
-
- void dgraf_Clear()
- /*
- Clear the display.
-
- Turbo C version.
- */
- {
- clearviewport();
- }
-
- #endif
-
-