home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
EXAMPLES
/
DEMOGRAB.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-09
|
17KB
|
784 lines
/*
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