home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
d
/
dots151.zip
/
GRAPHSRC.ZIP
/
GHI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-15
|
17KB
|
586 lines
/* plot - interface routine for Houstin Instruments plotter
history...
15 Jul 90 ver 1.30: can get parameters from configuration file
20 Jun 90 ver 1.27: Adapted to Turbo C. Improved file handling
(using only stream functions now, so output file need
not exist). Revised message wording.
25 Apr 89 dummy routines for flipping lines and setting background
color.
11 Sep 86 No logic seeking (starting at near end of line segment)
for dashed lines.
3 May 86 Default height corrected: size code 2.
Default plot height now 6 inches.
25 Apr 86 Implementing dashed lines in hardware.
19 Apr 86 Velocity is adjustable.
15 Apr 86 Assuming distance (and plot time) is proportional to
maximum of delx and dely.
Asking user to set origin with plotter controls.
Assuming pen is up after printing text.
Defining prim_attr.
bugs...
Should add some line feeds.
default file name should not be a port?
displayed text must not have '%', and '_', CR, LF, or TAB are replaced by ' '.
Could use \000 to terminate text strings.
Could delay getting pen until plotting is actually required.
needs test for presence of plotter...what's command ER "report"?
needs way to set character orientation.
Doesn't correctly get to near end of line segment.
bench needs to check for "erasing"
g3x needs to call set_height to set character size.
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "g.h"
#include "config.h"
#define streq !strcmp
#define EOT '_'
/* default margins, defined assuming portrait orientation */
#define LMARGIN 1.125
#define RMARGIN 1.125
#define TMARGIN 1.5
#define BMARGIN 1.5
#define BUFSIZE 80
/* imported variables */
extern char *default_script_file;
/* exported graphics variables */
char *machine = "Houstin Instruments DMP-29";
char *interface_version = "1.30";
char *config_file = NULL;
static char default_config_file[] = "GRAPHHI.CFG";
int plotting_device = 1;
int erasing = 0;
int flipping = 0;
int max_color = 7;
int current_color = 1;
int pixels_wide = 320; /* width of plot area in pixels */
int pixels_high = 200; /* height of plot area in pixels */
double best_width = 1.;
double best_height = .648; /* relative height/width parameters */
int pen_diameter = 3;
int char_rows = 25; /* text parameters */
int char_columns = 40;
int char_height = 8;
int char_width = 8;
int x_offset = 0;
int y_offset = 7;
int char_v_adjusted = 1;
int char_h_adjusted = 1;
int has_cursor_keys = 0;
int up_arrow = 0x48; /* cursor keys */
int down_arrow = 0x50;
int left_arrow = 0x4b;
int right_arrow = 0x4d;
int escaped_arrows = 1; /* cursor keys are preceded by 0 */
int escape_char = 0;
/* an 'A' on row r, column c has lower left corner on raster
r*char_height + y_offset
at pixel
c*char_width + x_offset */
struct PRIM_ATTR prim_attr=
{8, /* # colors */
1, /* # intensities */
0, /* nonzero if supported in hardware */
11, /* # linestyles in hardware */
0, /* # linestyles in software */
1, /* # linewidths */
0, /* nonzero if supported in hardware */
1, /* minimum linewidth */
1, /* maximum linewidth */
8, /* # pens in hardware */
0, /* # pens in software */
8, /* # fonts */
9, /* # character sizes */
1, /* nonzero if supported in hardware */
14, /* minimum character height (pixels) */
224, /* maximum character height (pixels) */
6, /* # markers in hardware */
0, /* # markers in software */
0 /* # pick IDs in hardware */
};
static draw();
static erase();
static text();
static character();
char *getenv();
static font=2;
static int plotter_type;
FILE *plot_file;
static file_open = 0;
static int style_code=1;
static int color_code=0;
static char styles[]=" 0123456789:";
static set_style(style) int style;
{ if(style<1) style=1;
else if(style>11) style=11;
if(style_code==style) return;
style_code=style;
fprintf(plot_file,"L%c ",styles[style_code]);
}
set_color(color) int color;
{ if(color<0) color=0;
else if(color>7) color=7;
if(color_code==color+1) return;
color_code=color+1;
fprintf(plot_file,"P%d ",color_code);
}
/* If no color has been set, use default (1st pen) */
static get_pen()
{ if(color_code==0) set_color(0);
}
set_intensity(intensity) double intensity; {}
set_background_color(color) int color; {}
set_background_intensity(intensity) double intensity; {}
inquire_color() {return (color_code-1);}
double inquire_intensity() {return 1.;}
/* draw - draw a straight line */
static cx=0,cy=0,down=0;
static int draw(x1,y1,x2,y2) int x1,y1,x2,y2;
{ int t,d1,d2;
get_pen();
y1= pixels_high-1-y1; y2= pixels_high-1-y2;
d1=maximum(abs(cx-x1),abs(cy-y1));
d2=maximum(abs(cx-x2),abs(cy-y2));
#ifdef DEBUG
printf("\nat (%d,%d) drawing (%d,%d)(%d away) to (%d,%d)(%d away)",
cx,cy,x1,y1,d1,x2,y2,d2);
#endif
if(d2<d1 && style_code==1)
{t=x1; x1=x2; x2=t; t=y1; y1=y2; y2=t; t=d1; d1=d2; d2=t;
#ifdef DEBUG
puts("swapping");
#endif
}
#ifdef DEBUG
putchar('\n');
#endif
if(d1)
{if(down) fprintf(plot_file,"U ");
fprintf(plot_file,"%d,%d D ",x1,y1); down=1;
}
else if (!down) {fprintf(plot_file,"D "); down=1;}
fprintf(plot_file,"%d,%d ",x2,y2);
cx=x2; cy=y2;
}
/* gotoxy - move pen to new position (used before text display) */
gotoxy(x,y) int x,y;
{ y= pixels_high-1-y;
if (x<0) x=0; else if (x>=pixels_wide) x=pixels_wide-1;
if (y<0) y=0; else if (y>=pixels_high) y=pixels_high-1;
if(x==cx && y==cy) return;
if(down) {fprintf(plot_file,"U "); down=0;}
fprintf(plot_file,"%d,%d ",x,y);
cx=x; cy=y;
}
static nil() {}
/* exported function pointers */
int (*draw_line)() = draw;
int (*erase_line)() = nil;
int (*draw_text)() = text;
int (*draw_char)() = character;
int (*flip_line)() = draw;
/* init - initialize the graphics system */
init_graphics()
{ int d1,d2,c,i,vel;
double w,h,left,bottom,hmax,wmax,xx,yy;
char buf[BUFSIZE],inbuf[BUFSIZE], *setup_string, *s;
static char *plotter_name = NULL;
static int offset_ask = 1,
size_ask = 1,
plotter_ask = 1,
velocity_ask = 1,
file_ask = 0;
static double offset[2] = {BMARGIN, RMARGIN};
static double velocity = {8.};
static double size[2] = {11. - BMARGIN - TMARGIN, 8.5 - LMARGIN - RMARGIN};
static char *port_name = NULL;
static PARAM parmv[] = {
{'o', REAL, &offset_ask, offset, 2},
{'l', REAL, &offset_ask, &offset[0]},
/* {'b', REAL, &offset_ask, &offset[1]}, */
{'s', REAL, &size_ask, size, 2},
{'w', REAL, &size_ask, &size[0]},
{'h', REAL, &size_ask, &size[1]},
/* {'p', BOOLEAN, &orientation_ask, &portrait, 0}, */
/* {'l', BOOLEAN, &orientation_ask, &landscape, 0}, */
{'f', STRING, &file_ask, &port_name, 1},
{'n', STRING, &plotter_ask, &plotter_name, 1},
{'v', REAL, &velocity_ask, &velocity, 1},
{'\0'}};
if(config_file == NULL) config_file = default_config_file;
config(config_file, NULL, parmv, buf, BUFSIZE);
if(version()>=0x200)
{if(plotter_name == NULL)
{plotter_name = getenv("PLOTTER");
}
else plotter_ask = 0;
}
while(1)
{if(plotter_ask)
{plotter_name = strcpy(buf,"DMP-29");
printf("Enter plotter name: DMP-29 or DMP-7 (default %s): ",
buf);
gets(inbuf);
if(inbuf[0]) strcpy(buf,inbuf);
strupr(plotter_name);
if(streq(plotter_name,"DMP-7") || streq(plotter_name, "7"))
{plotter_type=7; break;
}
if(streq(plotter_name,"DMP-29") || streq(plotter_name, "29"))
{plotter_type=29; break;
}
plotter_ask = 1;
}
}
if(plotter_type==7)
{prim_attr.hardware_linestyles=8;
prim_attr.charfont_count=1;
}
if(port_name == NULL && version() >= 0x200)
port_name = getenv("PLOT_PORT");
if(port_name == NULL)
{port_name = strncpy(buf, default_script_file, BUFSIZE-4);
s = strchr(port_name, '.');
if(s != NULL) *s = 0;
strcat(port_name, ".hi");
}
if(file_ask)
{port_name = strncpy(buf, port_name, BUFSIZE);
printf("Enter output file (default %s): ",buf);
gets(inbuf);
if(inbuf[0]) strcpy(buf,inbuf);
}
else
printf("\noutput written to %s\n", port_name);
unlink(port_name); /* delete the file if it exists */
plot_file=fopen(port_name,"w"); /* this will open a file or device */
if(plot_file==NULL) {printf("can\'t open output file %s", port_name); exit();}
file_open = 1;
setup_string = NULL;
if(version()>=0x200) setup_string = getenv("PLOT_SETUP");
if(setup_string == NULL)
setup_string = strcpy(buf,"\n\n\n;: EC5 V8 A 0,40 O @");
/* Default setup string...
Carriage return (allows auto baud rate),
plotter select, mode 1, .005" resolution,
8 in/sec,
absolute mode,
move .2 inches up and set origin,
deselect */
fixup_escapes(setup_string);
fprintf(plot_file,"%s", setup_string);
printf("Please...\n");
printf(" Position paper.\n");
printf(" Take tip protectors off the pens \
to be used and turn them over.\n");
printf("To put origin at top left of plot surface:\n");
printf(" Press \"LOCAL\" on plotter.\n");
printf(" Press \"small chart\".\n");
printf(" Press \"REMOTE\".\n");
printf("(type <return> when finished.)\n");
getchar();
vel=velocity;
if(velocity_ask)
{printf("\nEnter pen velocity (power of 2, default %2d in/sec): ",
vel);
gets(buf);
if(buf[0]) sscanf(buf,"%d",&vel);
}
if(vel>0)
{for (i=16; i>vel ; i /= 2) {}
vel=i;
}
else vel=8;
fprintf(plot_file,";: V%d ",vel);
/* plotter select, mode 1,
set velocity */
xx=offset[0];
yy=offset[1];
while(1)
{if(offset_ask)
{printf(
"\nEnter x and y displacement of plot origin in inches\n"
" (default %4.2f and %4.2f): ",
xx,yy);
}
gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&xx,&yy);
if(xx < -4. || 16. < xx)
printf("x displacement outside valid range -4...16\n");
else if(yy < -4. || 16. < yy)
printf("y displacement outside valid range -4...16\n");
else break;
offset_ask = 1;
xx = BMARGIN;
yy = 0.;
}
fprintf(plot_file, "%d,%d O ET%02x ", (int)(xx/.005),
(int)(yy/.005), EOT);
/* set origin,
end of text char */
w=size[0]; h=size[1];
while(1)
{if(size_ask)
{
printf("\nEnter width and height of plot area in inches \n");
printf(" (default, %5.3f by %5.3f): ", w, h);
gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&w,&h);
}
hmax = wmax = 17.;
h = floor(h*100. + .5)/100.;
w = floor(w*100. + .5)/100.;
if(w < .1 || w > wmax)
printf("width outside valid range 0.1 to %2.3f\n", wmax);
else if(h < .1 || h > hmax)
printf("height outside valid range 0.1 to %2.3f\n", hmax);
else break;
/* set defaults for next time */
h = 6.25;
w = 8.;
size_ask = 1;
}
/*
printf("\nEnter width and height of plot area in inches \n");
printf(" (default %5.2f by %5.2f): ",w,h);
gets(buf); if(buf[0]) sscanf(buf,"%lf %lf",&w,&h);
if(w<.1) w=.1; else if(w>17.) w=17.;
if(h<.1) h=.1; else if(h>17.) h=17.;
*/
pixels_wide=w/.005;
pixels_high=h/.005;
if(pixels_wide>=pixels_high) /* landscape style */
{best_width=1.;
best_height=(double)pixels_high/pixels_wide;
}
else /* portrait style */
{best_height=1.;
best_width=(double)pixels_wide/pixels_high;
}
set_height(28,28);
}
/* character sizes in units of .005 inch */
/* interpret escape sequences in setup string...
"$e" -> escape char,
"\n" -> line feed
"\r" -> carriage return
"\t" -> tab
"\c" -> c (escape an otherwise special character) */
fixup_escapes(s) char *s;
{ char *t;
for (t=s; *s; s++)
{if(*s=='$' && s[1]=='e') {*t++=0x1b; s++;}
else if(*s=='\\' && s[1]=='n') {*t++='\n'; s++;}
else if(*s=='\\' && s[1]=='t') {*t++='\t'; s++;}
else if(*s=='\\' && s[1]=='r') {*t++='\r'; s++;}
else if(*s=='\\') {*t++=s[1]; s++;}
else *t++=*s;
}
*t=0;
}
int size[9]={14, 21, 28, 42, 56, 84, 112, 168, 224};
char *size_code[9]={"1 ","1+","2 ","2+","3 ","3+","4 ","4+","5 "};
static text(s) char *s;
{ char *t,c;
get_pen();
t=s;
while(*t)
{c= *t&127;
if(c<32 || c>126 || c==EOT) *t=' ';
t++;
}
fprintf(plot_file,"S1%s%s%c U ",size_code[font],s,EOT);
down=0;
}
static character(c) char c;
{ if(c<32 || c>126 || c==EOT) return;
get_pen();
fprintf(plot_file,"S1%s%c%c U ",size_code[font],c,EOT);
down=0; cx=cy=-2000;
}
static set_height(width, height)
int width, height; /* height is in units of .005" */
{ if(height<size[0]) height=size[0];
else if(height>size[8]) height=size[8];
font=0;
while(height > size[font+1]) font++;
/* assert: size[font] < height <= size[font+1] */
if(height-size[font] > size[font+1]-height) font++;
char_width=char_height=size[font];
char_columns=pixels_wide/char_width;
char_rows=pixels_high/char_height;
x_offset=0; y_offset=char_height-1;
}
version() /* return MS-DOS version number. Version 2.01 returned as 0x201 */
{
#ifdef __DESMET__
extern unsigned _rax;
_rax=0x3000;
_doint(0x21);
return ( (_rax&0xff)<<8 | (_rax&0xff00)>>8 );
#else
#include <dos.h>
return ( (_version&0xff)<<8 | (_version&0xff00)>>8 );
#endif
}
#ifdef __DESMET__
/* search environment for given string */
getenv(target) char *target;
{ char buf[256],*s,t[25],*env, *malloc();
int nt,offset;
s=t;
while(*target) *s++=toupper(*target++);
*s++= '='; *s=0;
nt = strlen(t);
offset=0;
_lmove(2,44,_showcs()-0x10,&env,_showds());
while(1)
{_lmove(256,offset,env,buf,_showds());
s=buf;
if(*s)
{/* printf("examining entry: %s \n",s); getchar(); */
if (strncmp(t,s,nt)==0)
{env = malloc(strlen(s+nt)+1);
if(env == NULL) return NULL;
return strcpy(env, s+nt);
}
}
else return NULL;
offset+=strlen(buf)+1;
}
}
#endif /* DESMET */
/* finish - close down the graphics system */
finish_graphics()
{ if(file_open)
{fprintf(plot_file,"P0@");
fclose(plot_file);
file_open = 0;
puts("Please put caps back on pens.");
}
}
clear_graphics()
{ fprintf(plot_file,"H"); down=0;
puts("please replace paper (press <return> when finished)");
getchar();
}
/* pointers to optional functions (NULL if not implemented) */
int (*new_linestyle)()=set_style; /* (*new_linestyle)(style) int style; */
int (*new_linewidth)()=0; /* (*new_linewidth)(width) int width; */
int (*new_charsize)()=set_height; /* (*new_charsize)(w,h) int w,h; */
int (*draw_marker)()=0; /* (*draw_marker)(n) int n; */
#ifdef MAIN
main()
{ char buf[100];
printf("Interface %s for the %s\n",interface_version,machine);
init_graphics();
printf("screen width %d pixels\nheight %d pixels\n",
pixels_wide,pixels_high);
printf("height:width ratio %f:%f\n",best_height,best_width);
printf("%d colors\n",max_color+1);
printf("primitive attributes...\n");
printf("color_count= %d \n",prim_attr.color_count);
printf("intensity_count= %d \n",prim_attr.intensity_count);
printf("intensities_in_hardware= %d \n",prim_attr.intensities_in_hardware);
printf("hardware_linestyles= %d \n",prim_attr.hardware_linestyles);
printf("software_linestyles= %d \n",prim_attr.software_linestyles);
printf("linewidth_count= %d \n",prim_attr.linewidth_count);
printf("linewidths_in_hardware= %d \n",prim_attr.linewidths_in_hardware);
printf("linewidth_minimum= %d \n",prim_attr.linewidth_minimum);
printf("linewidth_maximum= %d \n",prim_attr.linewidth_maximum);
printf("hardware_pens= %d \n",prim_attr.hardware_pens);
printf("software_pens= %d \n",prim_attr.software_pens);
printf("charfont_count= %d \n",prim_attr.charfont_count);
printf("charsize_count= %d \n",prim_attr.charsize_count);
printf("charsize_in_hardware= %d \n",prim_attr.charsize_in_hardware);
printf("charsize_minimum= %d \n",prim_attr.charsize_minimum);
printf("charsize_maximum= %d \n",prim_attr.charsize_maximum);
printf("hardware_markers= %d \n",prim_attr.hardware_markers);
printf("software_markers= %d \n",prim_attr.software_markers);
printf("pick_id_count= %d \n",prim_attr.pick_id_count);
(*draw_line)(2,4,200,-400);
(*draw_line)(20,40,100,-200);
(*erase_line)(2,4,200,-400);
(*draw_line)(10,30,100,300);
(*draw_line)(10,40,500,890);
(*draw_line)(10,40,500,32);
(*draw_line)(10,1000,78,8900);
gotoxy(10,-20);
(*draw_text)("hello\nDolly");
(*draw_char)('A');
finish_graphics();
}
#endif
maximum(a,b) int a,b;
{ if (a>b) return a;
return b;
}