/*_______________________________________________________________
tc-007.c
Function: This program demonstrates how to produce high-impact
business graphics.
Compatibility: Supports all graphics adapters and monitors.
The software uses the 640x200 16-color mode if a VGA or EGA is
present; the 640x200 2-color mode if a CGA or MCGA is present.
Remarks: Refer to the book.
Copyright 1988 Lee Adams and TAB BOOKS Inc.
_________________________________________________________________
I N C L U D E F I L E S */
#include <dos.h> /* supports the BIOS call */
#include <stdio.h> /* supports the printf function */
#include <graphics.h> /* supports the graphics functions */
/*_______________________________________________________________
D E C L A R A T I O N S */
char fill_3[]={0,32,0,0,0,2,0,0}; /* 3% fill */
char fill_6[]={32,0,2,0,128,0,8,0}; /* 6.25% fill */
char fill_12[]={32,2,128,8,32,2,128,8}; /* 12.5% fill */
char fill_25[]={68,17,68,17,68,17,68,17}; /* 25% fill */
char fill_37[]={146,41,148,73,164,73,146,73}; /* 37.5% fill */
char fill_50[]={85,170,85,170,85,170,85,170}; /* 50% fill */
char fill_62[]={109,214,107,182,91,182,109,182}; /* 62.5% fill */
char fill_75[]={187,238,187,238,187,238,187,238}; /* 75% fill */
char fill_87[]={223,253,127,247,223,253,127,247}; /* 87.5% fill */
void keyboard(void);void quit_pgm(void);
void notice(float x,float y);
void coords(void);void graphics_setup(void);
int fg=1; /* foreground color */
float sx,sy,sx1,sy1,sx2,sy2;
float sybase;
float x_res,y_res;
int C0=0,C1=1,C2=2,C3=3,C4=4,C5=5,C6=6,C7=7,C8=8,C9=9,C10=10,
C11=11,C12=12,C13=13,C14=14,C15=15,mode_flag=0;
/*_______________________________________________________________
M A I N R O U T I N E */
main(){
graphics_setup(); /* establish graphics mode */
fg=C1;
/* draw the background */
setfillpattern(fill_6,fg);
sx=70;sy=38;coords();sx1=sx;sy1=sy;
sx=639;sy=72;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_12,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=108;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_25,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=144;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_37,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=180;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_50,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=216;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_62,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=252;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_75,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=288;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillpattern(fill_87,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=324;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,fg);
sx=70;coords();sx1=sx;sy1=sy2+1;
sx=639;sy=396;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
/* draw the axis display */
if (mode_flag==4) C7=0;
setfillstyle(SOLID_FILL,C7);
sx=80;sy=60;coords();sx1=sx;sy1=sy;
sx=85;sy=384;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
sx=80;sy=380;coords();sx1=sx;sy1=sy;sybase=sy-1;
sx=600;sy=384;coords();sx2=sx;sy2=sy;
bar(sx1,sy1,sx2,sy2);
/* display the text labels */
if (mode_flag==4) C7=1;
setcolor(C7);moveto(112,168);
outtext("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec");
setcolor(C12);moveto(184,176);
outtext("M O N T H L Y S A L E S T O D A T E");
setcolor(C7);moveto(24,24);outtext("SALES");
moveto(0,40);outtext("$100,000");
moveto(0,64);outtext("$ 80,000");
moveto(0,88);outtext("$ 60,000");
moveto(0,112);outtext("$ 40,000");
moveto(0,136);outtext("$ 20,000");
/* draw the monthly levels */
setfillstyle(SOLID_FILL,C14);
sx=108;sy=204;coords();sx1=sx;sy1=sy;
sx=138;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C10);
sx=148;sy=178;coords();sx1=sx;sy1=sy;
sx=178;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C11);
sx=188;sy=240;coords();sx1=sx;sy1=sy;
sx=218;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C13);
sx=228;sy=264;coords();sx1=sx;sy1=sy;
sx=258;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C14);
sx=268;sy=175;coords();sx1=sx;sy1=sy;
sx=298;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C10);
sx=308;sy=144;coords();sx1=sx;sy1=sy;
sx=338;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C11);
sx=348;sy=134;coords();sx1=sx;sy1=sy;
sx=378;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setfillstyle(SOLID_FILL,C7);
sx=388;sy=139;coords();sx1=sx;sy1=sy;
sx=418;coords();sx2=sx;sy2=sybase;
bar(sx1,sy1,sx2,sy2);
setcolor(C7);
sx=428;sy=115;coords();sx1=sx;sy1=sy;
sx=458;coords();sx2=sx;sy2=sybase+1;
rectangle(sx1,sy1,sx2,sy2);
sx=468;sy=110;coords();sx1=sx;sy1=sy;
sx=498;coords();sx2=sx;sy2=sybase+1;
rectangle(sx1,sy1,sx2,sy2);
sx=508;sy=106;coords();sx1=sx;sy1=sy;
sx=538;coords();sx2=sx;sy2=sybase+1;
rectangle(sx1,sy1,sx2,sy2);
sx=548;sy=101;coords();sx1=sx;sy1=sy;
sx=578;coords();sx2=sx;sy2=sybase+1;
rectangle(sx1,sy1,sx2,sy2);
if (mode_flag==4) C7=1;
setcolor(C7);notice(0,0);
keyboard(); /* wait for user to press <Esc> */
quit_pgm(); /* end the program gracefully */
}
/*_______________________________________________________________
SUBROUTINE: CHECK THE KEYBOARD BUFFER */
void keyboard(void){
union u_type {int a;char b[3];} keystroke;
int get_keystroke(void); /* declare a local subroutine */
do keystroke.a=get_keystroke();
while (keystroke.b[0]!=27); /* return if <Esc> is pressed */
}
/* LOCAL SUBROUTINE: RETRIEVE ONE KEYSTROKE */
int get_keystroke(void){
union REGS regs;regs.h.ah=0;return int86(0x16,®s,®s);}
/*_______________________________________________________________
SUBROUTINE: GRACEFUL EXIT FROM THE PROGRAM */
void quit_pgm(void){
cleardevice();restorecrtmode();exit(0);}
/*______________________________________________________________
SUBROUTINE: VGA/EGA/CGA/MCGA compatibility module
The 640x200 16-color mode is established if a VGA or EGA is
present. The 640x200 2-color mode is invoked if a CGA or MCGA
is present. */
void graphics_setup(void){
int graphics_adapter,graphics_mode;
detectgraph(&graphics_adapter,&graphics_mode);
if (graphics_adapter==VGA) goto VGA_EGA_mode; /* if VGA */
if (graphics_mode==EGAHI) goto VGA_EGA_mode; /* if EGA and ECD */
if (graphics_mode==EGALO) goto VGA_EGA_mode; /* if EGA and SCD */
if (graphics_adapter==CGA) goto CGA_mode; /* if CGA */
if (graphics_adapter==MCGA) goto MCGA_mode; /* if MCGA */
goto abort_message; /* if no VGA, EGA, CGA, or MCGA */
VGA_EGA_mode: /* establish 640x200 16-color mode */
graphics_adapter=EGA;graphics_mode=EGALO;
initgraph(&graphics_adapter,&graphics_mode,"");
x_res=640;y_res=200;mode_flag=3;setcolor(C7);
outtextxy(216,192,"640x200 16-color VGA and EGA mode.");
outtextxy(200,0,"USING C TO PRODUCE BUSINESS GRAPHICS");
return;
CGA_mode: /* establish 640x200 2-color mode */
graphics_adapter=CGA;graphics_mode=CGAHI;
initgraph(&graphics_adapter,&graphics_mode,"");
x_res=640;y_res=200;C0=0;C1=1;C2=1;C3=1;C4=1;C5=1;C6=1;C7=1;
C8=1;C9=1;C10=1;C11=1;C12=1;C13=1;C14=1;C15=1;
mode_flag=4;setcolor(C7);
outtextxy(240,192,"640x200 2-color CGA mode.");
outtextxy(200,0,"USING C TO PRODUCE BUSINESS GRAPHICS");
return;
MCGA_mode: /* establish 640x200 2-color mode */
graphics_adapter=MCGA;graphics_mode=MCGAHI;
initgraph(&graphics_adapter,&graphics_mode,"");
x_res=640;y_res=200;C0=0;C1=1;C2=1;C3=1;C4=1;C5=1;C6=1;C7=1;
C8=1;C9=1;C10=1;C11=1;C12=1;C13=1;C14=1;C15=1;
mode_flag=4;setcolor(C7);
outtextxy(240,192,"640x200 2-color MCGA mode.");
outtextxy(200,0,"USING C TO PRODUCE BUSINESS GRAPHICS");
return;
abort_message:
printf("\n\nUnable to proceed.\n");
printf("Requires VGA, EGA, MCGA, or CGA adapter\n");
printf(" with appropriate monitor.\n");
printf("Please refer to the book.\n\n");
exit(0);
}
/*_______________________________________________________________
SUBROUTINE: coords()
This subroutine accepts sx,sy device-independent display
coordinates and returns sx,sy device-dependent screen
coordinates scaled to fit the 640x480, 640x350, 640x200, or
320x200 screen, depending upon the graphics mode being used. */
void coords(void){
sx=sx*(x_res/640);sy=sy*(y_res/480);return;}
/*_______________________________________________________________
SUBROUTINE: Copyright Notice
This subroutine displays the standard copyright notice.
If you are typing in this program from the book you can
safely omit this subroutine, provided that you also remove
the instruction "notice()" from the main routine. */
int copyright[][3]={0x7c00,0x0000,0x0000,0x8231,
0x819c,0x645e,0xba4a,0x4252,0x96d0,0xa231,0x8252,0x955e,0xba4a,
0x43d2,0xf442,0x8231,0x825c,0x945e,0x7c00,0x0000,0x0000};
void notice(float x, float y){
int a,b,c; int t1=0;
for (t1=0;t1<=6;t1++){a=copyright[t1][0];b=copyright[t1][1];
c=copyright[t1][2];
setlinestyle(USERBIT_LINE,a,NORM_WIDTH);
moveto(x,y);lineto(x+15,y);
setlinestyle(USERBIT_LINE,b,NORM_WIDTH);
moveto(x+16,y);lineto(x+31,y);
setlinestyle(USERBIT_LINE,c,NORM_WIDTH);
moveto(x+32,y);lineto(x+47,y);y=y+1;};
setlinestyle(USERBIT_LINE,0xFFFF,NORM_WIDTH);
return;}
/*_______________________________________________________________
End of source code */