home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QBasic & Borland Pascal & C
/
Delphi5.iso
/
C
/
Samples
/
CSAPE32.ARJ
/
EXAMPLES
/
DEMOGRAF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-09
|
18KB
|
790 lines
/*
demograf.c
C-scape 3.2 Example Program
Copyright (c) 1989, 1990 by Oakland Group, Inc.
ALL RIGHTS RESERVED.
This program demonstrates how C-scape screens can be placed
on top of graphics images.
This program relies on the compiler supplied graphics library
to draw the graphic images.
The following graphics libraries are supported:
Note: THIS PROGRAM MUST BE COMPILED IN LARGE MODEL !!!
(it needs more than 64k of data)
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:
-----------------
11/15/89 pmcm added more detailed error messages
11/15/89 pmcm added error checking on modes not supported by TC or MS
11/15/89 pmcm added cases for Herc & Cpq40 mode support to TC version
1/31/90 jmd added environment variable support
3/12/90 jql corrected a spelling error in the horoscopes
4/01/90 jmd ansi-fied
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)
11/02/90 ted added m6, tc++ support.
12/01/90 ted added oak_notused() macro to suppress warnings.
12/01/90 ted prototyped main, except if Turbo C++.
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 "ostdlib.h"
#include "popdecl.h"
#include "framer.h"
#include "pcmode.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 includes -------------*/
/*** data structure to hold information about the demo ***/
typedef struct {
int shape; /* current shape type */
int size; /* current shape size */
int color; /* current painting color */
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 BLANK 998 /* positive for compat w/ cs31 */
#define QUIT 999
#define MIXED 999
/*** Function prototypes ***/
/* Turbo C++ complains if main is prototyped */
#ifndef TCP
int main(void);
#endif
int draw(dgraf_struct *dgrafp);
/* User functions connected to pulldown menu */
int u_erase(VOID *pdata, int idata);
int u_shape(VOID *pdata, int idata);
int u_size(VOID *pdata, int idata);
int u_color(VOID *pdata, int idata);
int u_horoscope(VOID *pdata, int idata);
/* 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);
void dgraf_Ellipse(opbox *opboxp, int color);
/*** The pulldown menu definition ***/
struct frame_def main_menu[] = {
{ "Erase", u_erase, BLANK},
{ FRAME_END },
{ "Figure", FNULL, BLANK},
{ " Mixed ", u_shape, MIXED},
{ " Line ", u_shape, 1},
{ " Circle ", u_shape, 2},
{ " Square ", u_shape, 3},
{ FRAME_END },
{ "Size", FNULL, BLANK},
{ " Mixed ", u_size, MIXED},
{ " Small ", u_size, 1},
{ " Medium ", u_size, 2},
{ " Large ", u_size, 3},
{ FRAME_END },
{ "Color", FNULL, BLANK},
{ " Mixed ", u_color, MIXED},
{ " Single ", u_color, 1},
{ FRAME_END },
{ "Horoscope", FNULL, BLANK},
{ " Fast ", u_horoscope, 5},
{ " Medium ", u_horoscope, 3},
{ " Slow ", u_horoscope, 1},
{ FRAME_END },
{ "Quit", FNULL, QUIT},
{ FRAME_END },
{ FRAME_END },
};
/*----------------------------- MAIN -----------------------------------------*/
int main(void)
{
dgraf_struct dgraf;
sed_type frame;
int ret, key, x;
/*
Initialize the C-scape device interface:
def_ModeGraphics selects best available graphics mode;
grwin_Class saves graphic in the background window
*/
if (!disp_Init(def_ModeGraphics, grwin_Class)) {
printf("\nDEMOGRAF: No graphics hardware found; or, ");
printf("\n -- Or, there is insufficient memory to initialize the OWL ...");
printf("\n (this program requires a large memory model compilation).\n");
exit(1);
return(1);
}
/* map colors for 2 color video modes */
if (disp_GetColors() <= 2L) {
disp_MapMono(TRUE);
}
/* Initialize Graphics Library */
if ((x = dgraf_Init(&dgraf)) != 0) {
disp_Close();
#ifdef __TURBOC__ /* Turbo C */
switch(x) {
case -2:
printf("\nDEMOGRAF: Turbo C initgraph cannot detect graphics card.\n");
break;
case -3:
printf("\nDEMOGRAF: Turbo C initgraph cannot find BGI driver file.\n");
break;
case -4:
printf("\nDEMOGRAF: Turbo C initgraph does not support this video hardware.\n");
break;
case -5:
printf("\nDEMOGRAF: Turbo C initgraph insufficient memory to load driver.\n");
break;
default:
printf("\nDEMOGRAF: Turbo C initgraph error %d.\n", x);
break;
}
#else
printf("\nDEMOGRAF: Microsoft C _setvideomode does not support this video hardware.\n");
#endif
exit(1);
return(1);
}
/* Create the pulldown menu bar */
frame = frame_Open(main_menu, bd_1, dgraf.reg, dgraf.sel, dgraf.reg);
frame_Repaint(frame);
while (TRUE) {
while (!kb_Check()) {
draw(&dgraf);
}
/* key pressed, read it and call pulldown menu */
key = kb_Read();
if ((ret = frame_Go(frame, key, (VOID *) &dgraf )) == QUIT) {
/* Quit selected, break out of while loop */
break;
}
/* if first letter search of menu failed, try again */
else if (ret == 0) {
if (frame_Go(frame, ' ', (VOID *) &dgraf ) == QUIT) {
/* Quit selected, break out of while loop */
break;
}
}
}
/* close down device interface */
disp_Close();
exit(0);
return(0);
}
int draw(dgraf_struct *dgrafp)
/*
Draws a shape using the current information
in the dgraf structure.
*/
{
int shape, size, color;
opbox box;
shape = (dgrafp->shape == MIXED) ? nrand(3) + 1 : dgrafp->shape;
size = (dgrafp->size == MIXED) ? nrand(3) + 1: dgrafp->size;
color = (dgrafp->color == MIXED) ? nrand(dgrafp->ncolors) : dgrafp->color;
box.ymin = nrand(dgrafp->hgt);
box.xmin = nrand(dgrafp->wid);
box.ymax = box.ymin + (dgrafp->hgt)/10 * size;
box.xmax = box.xmin + (dgrafp->wid)/10 * size;
switch(shape) {
case 1:
dgraf_Line(&box, color);
break;
case 2:
dgraf_Ellipse(&box, color);
break;
case 3:
dgraf_Rectangle(&box, color);
break;
}
return(TRUE);
}
/*---------------------------------------------------------------------------*/
/* User functions: functions called from the pull down menu */
/* pdata is a pointer to the dgraf struct and is passed via frame_Go */
int u_erase(VOID *pdata, int idata)
/*
Erase the display
*/
{
oak_notused(pdata);
oak_notused(idata);
dgraf_Clear();
return(1);
}
int u_shape(VOID *pdata, int idata)
/*
Change the current shape to idata's value
idata is defined in the menu definition structure.
*/
{
dgraf_struct *dgrafp;
dgrafp = (dgraf_struct *) pdata;
dgrafp->shape = idata;
return(1);
}
int u_size(VOID *pdata, int idata)
/*
Change the current size to idata's value
idata is defined in the menu definition structure.
*/
{
dgraf_struct *dgrafp;
dgrafp = (dgraf_struct *)pdata;
dgrafp->size = idata;
return(1);
}
int u_color(VOID *pdata, int idata)
/*
Change the current color to idata's value
idata is defined in the menu definition structure.
*/
{
dgraf_struct *dgrafp;
dgrafp = (dgraf_struct *)pdata;
dgrafp->color = idata;
return(1);
}
char *horoscope_msg[] = {
"AQUARIUS\nYou will find a substanstial amount of cash in your toothpaste.",
"PISCES\nYou will be the Elvis of the nineties.",
"ARIES\nA surprise gift of a lawn ornament is not out of the question.",
"TAURUS\nA dream about cows carries a clue to building a better life for yourself.",
"GEMINI\nAll your hard work will pay off; aluminum siding is yours for the asking.",
"CANCER\nA ringing pay phone holds your key to a world of fun.",
"LEO\nYou are too busy to waste time on horoscopes.",
"VIRGO\nA warped bowling alley will lead you to a major scientific discovery.",
"LIBRA\nYou will star in a major motion picture with Garrett Morris.",
"SCORPIO\nYou need a good change of pace. Purchase some imported cheeses.",
"SAGITTARIUS\nGood times ahead, despite a boring horoscope.",
"CAPRICORN\nUnexpected company will be dropping in. Be sure your bathroom is tidy."
};
#define COUNT (sizeof(horoscope_msg) / sizeof(char *))
int u_horoscope(VOID *pdata, int idata)
/*
Slides a window across the display.
idata determines the speed of the horoscope.
idata comes from the framer definition structure.
*/
{
sed_type sed;
int col;
dgraf_struct *dgrafp;
dgrafp = (dgraf_struct *)pdata;
/* Create a message window */
sed = pop_Text(horoscope_msg[nrand(COUNT)], 10, disp_GetWidth(), -1, 22, dgrafp->reg, bd_1);
/* Slide the window across the display */
for (col = disp_GetWidth(); col > -20; col -= idata) {
sed_SetPosition(sed, 10, col);
}
/* Destroy the window */
sed_Close(sed);
return(TRUE);
}
/*---------------------------------------------------------------------------*/
/*
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)
/*
Initialize the graphics library.
Initialize demo data.
Returns
0 if successful
-1 if the video hardware is unsupported by MS.
Microsoft version.
*/
{
struct videoconfig config; /* Microsoft defined structure */
int char_height; /* height of characters in pixels */
int mode;
switch(pc_GetMode()) {
case 0x13:
mode = _MRES256COLOR;
char_height = 8;
break;
case 0x12:
mode = _VRES16COLOR;
char_height = 16;
break;
case 0x11:
mode = _VRES2COLOR;
char_height = 16;
break;
case 0x10:
mode = _ERESCOLOR;
char_height = 16;
break;
case 0x0f:
mode = _ERESNOCOLOR;
char_height = 14;
break;
case 0x0e:
mode = _HRES16COLOR;
char_height = 8;
break;
case 0x0d:
mode = _MRES16COLOR;
char_height = 8;
break;
case 0x06:
mode = _HRESBW;
char_height = 8;
break;
case 0x05:
case 0x04:
mode = _MRESNOCOLOR;
char_height = 8;
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;
char_height = 14;
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 clip region to avoid drawing over menu bar */
_setcliprgn(0, char_height, config.numxpixels - 1, config.numypixels - 1);
/* set up dgraf data */
dgrafp->shape = MIXED;
dgrafp->size = MIXED;
dgrafp->color = MIXED;
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_Ellipse(opbox *opboxp, int color)
/*
Draw an ellipse bounded by the rectangle with corners
(opboxp->xmin, opboxp->ymax) (opboxp->xmax, opboxp->ymax)
with color color.
Microsoft version.
*/
{
_setcolor(color);
_ellipse(_GBORDER, 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;
int char_height; /* height of characters in pixels */
char *bgipath;
switch(pc_GetMode()) {
case 0x12:
driver = VGA;
mode = VGAHI;
char_height = 16;
break;
case 0x11:
driver = MCGA;
mode = MCGAHI;
char_height = 16;
break;
case 0x10:
driver = EGA;
mode = EGAHI;
char_height = 16;
break;
case 0x0f:
driver = EGAMONO;
mode = EGAMONOHI;
char_height = 14;
break;
case 0x0e:
driver = EGA;
mode = EGALO;
char_height = 8;
break;
case 0x06:
driver = CGA;
mode = CGAHI;
char_height = 8;
break;
case 0x05:
case 0x04:
driver = CGA;
mode = CGAC1;
char_height = 8;
break;
case 0x10A:
case 0x10B:
driver = HERCMONO;
mode = HERCMONOHI;
char_height = 14;
break;
case 0x140: /* Compaq plasma mode 40 */
driver = ATT400;
mode = ATT400HI;
char_height = 16;
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 clip region to avoid drawing over menu bar */
setviewport(0, char_height, getmaxx(), getmaxy(), TRUE);
/* set up dgraf data */
dgrafp->shape = MIXED;
dgrafp->size = MIXED;
dgrafp->color = MIXED;
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);
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_Ellipse(opbox *opboxp, int color)
/*
Draw an ellipse bounded by the rectangle with corners
(opboxp->xmin, opboxp->ymax) (opboxp->xmax, opboxp->ymax)
with color color.
Turbo C version.
Note: This really draws circles not ellipses...
*/
{
int rad, x, y;
x = opboxp->xmin + ((opboxp->xmax - opboxp->xmin) / 2);
y = opboxp->ymin + ((opboxp->ymax - opboxp->ymin) / 2);
rad = (opboxp->xmax - opboxp->xmin) / 2;
setcolor(color);
circle(x, y, rad);
}
void dgraf_Clear()
/*
Clear the display.
Turbo C version.
*/
{
clearviewport();
}
#endif
/*---------------------------------------------------------------------------*/