1*12240Sslatteng /* @(#)graphics1.c 1.3 05/05/83
211951Sslatteng *
311951Sslatteng * Copyright -C- 1982 Barry S. Roitblat
411951Sslatteng *
511951Sslatteng *
611951Sslatteng * This file contains primitive functions to manipulate an AED512
711951Sslatteng * color display.
811951Sslatteng *
911951Sslatteng * (Modified from software written by John Ousterhout for the caesar
1011951Sslatteng * program)
1111951Sslatteng */
1211951Sslatteng #include "gremlin.h"
1311951Sslatteng #include <sgtty.h>
1411951Sslatteng
1511951Sslatteng /* The following variables are used to hold state that we keep around
1611951Sslatteng * between procedure calls in order to reduce the amount of information
1711951Sslatteng * that must be shipped to the terminal.
1811951Sslatteng */
1911951Sslatteng
2011951Sslatteng static char dbuf[BUFSIZ]; /* Used to buffer display characters */
2111951Sslatteng static struct sgttyb sgttyb; /* Used to save terminal control bits */
2211951Sslatteng static int sgflags; /* Used to save flags from sgttyb */
2311976Sslatteng static char sgispeed, sgospeed; /* Used to save baud rates */
2411951Sslatteng static int localmode; /* Used to save terminal local mode word */
2511951Sslatteng static curcharsize; /* Current character size */
2611951Sslatteng static int wmask; /* Current write mask value */
2711951Sslatteng
2811951Sslatteng
2911951Sslatteng /* The following strings are used to as the colors for drawing and
3011951Sslatteng * erasing. They permit layer inversion, such that the drawing of
3111951Sslatteng * the layer causes zeroes to be written and erasing causes ones to
3211951Sslatteng * be written.
3311951Sslatteng */
3411951Sslatteng
3511951Sslatteng static char draw[4], erase[4];
3611951Sslatteng
3711951Sslatteng /* The following arrays are used to define the line styles we use for
3811951Sslatteng * for drawing. Color and stipple are used as a representation of
3911951Sslatteng * styles on the AED but are not necessarily accurate with the final
4011951Sslatteng * output.
4111951Sslatteng */
4211951Sslatteng
4311951Sslatteng static int stylecolor[11] = { 0, 041, 041, 043, 041, 041, 042,
4411951Sslatteng 044, 044, 0200, 0100 };
4511951Sslatteng static int stipple[11] = { 255, 136, 228, 255, 240, 255, 255,
4611951Sslatteng 255, 255, 136, 255 };
4711951Sslatteng
4811951Sslatteng /* The following table contains the color lookup used to represent
4911951Sslatteng * different fonts on the AED.
5011951Sslatteng */
5111951Sslatteng
5211951Sslatteng static int fontmap[8] = { 0, 041, 044, 045, 046, 0, 0, 0 };
5311951Sslatteng
5411951Sslatteng /* The following variables are made available to the outside world. */
5511951Sslatteng
5611951Sslatteng int GrXMax = 511; /* Maximum x-coordinate of screen */
5711951Sslatteng int GrYMax = 482; /* Maximum y-coordinate of screen */
5811951Sslatteng FILE *display; /* The file for the AED512 */
5911951Sslatteng int charxsize; /* Character x dimension */
6011951Sslatteng int charysize; /* Character y dimension */
6111951Sslatteng int descenders; /* Character descender length */
6211951Sslatteng int curx, cury; /* Current access position */
6311951Sslatteng int rmask; /* read mask */
6411951Sslatteng
6511951Sslatteng /* The following table is used to convert numbers to hex. We cannot use
6611951Sslatteng * standard C library conversion because it generates lower case letters
6711951Sslatteng * which are bad news to the AED512.
6811951Sslatteng */
6911951Sslatteng
7011951Sslatteng static char hex[] = "0123456789ABCDEF";
7111951Sslatteng
7211976Sslatteng
7311951Sslatteng #ifndef FASTIO
GRchex(val,string,nchars)7411951Sslatteng GRchex(val, string, nchars)
7511951Sslatteng int val; /* Integer value to be converted. */
7611951Sslatteng char *string; /* Pointer to string area to be used for
7711951Sslatteng * converted result.
7811951Sslatteng */
7911951Sslatteng int nchars; /* Number of characters to be converted. */
8011951Sslatteng
8111951Sslatteng /*---------------------------------------------------------
8211951Sslatteng * This is a routine that converts an integer to a string
8311951Sslatteng * of hexadecimal characters.
8411951Sslatteng *
8511951Sslatteng * Results: None.
8611951Sslatteng *
8711951Sslatteng * Side Effects:
8811951Sslatteng * The string contains the value of the low-order nchars 4-bit chunks
8911951Sslatteng * of val, as represented in hexadecimal. String is zero-filled.
9011951Sslatteng *---------------------------------------------------------
9111951Sslatteng */
9211951Sslatteng
9311951Sslatteng {
9411951Sslatteng string = &(string[nchars]);
9511951Sslatteng *string = '\0';
9611951Sslatteng for (; nchars>0 ; nchars--)
9711951Sslatteng {
9811951Sslatteng *(--string) = hex[val & 017];
9911951Sslatteng val >>= 4;
10011951Sslatteng }
10111951Sslatteng }
10211951Sslatteng #endif
10311951Sslatteng
GRsetwmask(mask)10411951Sslatteng GRsetwmask(mask)
10511951Sslatteng int mask; /* New value for write mask */
10611951Sslatteng
10711951Sslatteng /*---------------------------------------------------------
10811951Sslatteng * This is a routine that resets the value of the current
10911951Sslatteng * write mask, if necessary.
11011951Sslatteng *
11111951Sslatteng * Results: None.
11211951Sslatteng *
11311951Sslatteng * Side Effects:
11411951Sslatteng * If wmask is different from mask, then the new mask is output to
11511951Sslatteng * the display and stored in wmask.
11611951Sslatteng *
11711951Sslatteng * Errors: None.
11811951Sslatteng *---------------------------------------------------------
11911951Sslatteng */
12011951Sslatteng
12111951Sslatteng {
12211951Sslatteng char s[4];
12311951Sslatteng wmask = mask;
12411951Sslatteng #ifndef FASTIO
12511951Sslatteng GRchex(wmask, s, 2);
12611951Sslatteng fprintf(display, "L%s", s);
12711951Sslatteng #else
12811951Sslatteng putc('L', display);
12911951Sslatteng putc(mask&0377, display);
13011951Sslatteng #endif
13111951Sslatteng }
13211951Sslatteng
GRsetcolor(color)13311951Sslatteng GRsetcolor(color)
13411951Sslatteng int color;
13511951Sslatteng /*
13611951Sslatteng * This routine sets the current color for the graphics display
13711951Sslatteng */
13811951Sslatteng
13911951Sslatteng {
14011951Sslatteng
14111951Sslatteng #ifndef FASTIO
14211951Sslatteng char s1[3];
14311951Sslatteng
14411951Sslatteng GRchex(color, s1, 2);
14511951Sslatteng fprintf(display, "C%s",s1);
14611951Sslatteng #else
14711951Sslatteng fprintf(display,"C%c", color&0377);
14811951Sslatteng #endif
14911951Sslatteng
15011951Sslatteng } /* end setcolor */
15111951Sslatteng
15211976Sslatteng
GRoutxy20(x,y)15311951Sslatteng GRoutxy20(x, y)
15411951Sslatteng int x,y; /* The coordinates to be output */
15511951Sslatteng
15611951Sslatteng /*---------------------------------------------------------
15711951Sslatteng * This routine outputs an x-y coordinate pair in the standard
15811951Sslatteng * format required by the AED display.
15911951Sslatteng *
16011951Sslatteng * Results: None.
16111951Sslatteng *
16211951Sslatteng * Side Effects:
16311951Sslatteng * Characters are output to the AED512 in the standard way required
16411951Sslatteng * for values indicated by "xy20" in the user manual.
16511951Sslatteng *
16611951Sslatteng * Errors: None.
16711951Sslatteng *
16811951Sslatteng * (Modified from software written by John Ousterhout for the caesar
16911951Sslatteng * program)
17011951Sslatteng *---------------------------------------------------------
17111951Sslatteng */
17211951Sslatteng
17311951Sslatteng {
17411951Sslatteng #ifndef FASTIO
17511951Sslatteng char s1[4], s2[4], s3[4];
17611951Sslatteng GRchex(((y>>8)&03) | ((x>>6)&014), s1, 1);
17711951Sslatteng GRchex(x&0377, s2, 2);
17811951Sslatteng GRchex(y&0377, s3, 2);
17911951Sslatteng fprintf(display, "%s%s%s", s1, s2, s3);
18011951Sslatteng #else
18111951Sslatteng putc(((x>>4)&020)+((y>>8)&01), display);
18211951Sslatteng putc(x&0377, display);
18311951Sslatteng putc(y&0377, display);
18411951Sslatteng #endif
18511951Sslatteng }
18611951Sslatteng
GRsetpos(x,y)18711951Sslatteng GRsetpos(x, y)
18811951Sslatteng int x, y; /* Screen coordinates.
18911951Sslatteng
19011951Sslatteng /*---------------------------------------------------------
19111951Sslatteng * This routine sets the current access position, if necessary.
19211951Sslatteng *
19311951Sslatteng * Results: None.
19411951Sslatteng *
19511951Sslatteng * Side Effects:
19611951Sslatteng * If x and y are equal to curx and cury, respectively, then nothing
19711951Sslatteng * happens. Otherwise, x and y are stored into curx and cury and the
19811951Sslatteng * current access position of the AED is set to those coordinates.
19911951Sslatteng *
20011951Sslatteng * Errors: None.
20111951Sslatteng *---------------------------------------------------------
20211951Sslatteng */
20311951Sslatteng
20411951Sslatteng {
20511951Sslatteng if (x==curx && y==cury) return;
20611951Sslatteng curx = x;
20711951Sslatteng cury = y;
20811951Sslatteng putc('Q', display);
20911951Sslatteng GRoutxy20(x, y);
21011951Sslatteng }
21111951Sslatteng
21211976Sslatteng
GRsetcharstyle(style)21311951Sslatteng GRsetcharstyle(style)
21411951Sslatteng int style; /* New font. */
21511951Sslatteng
21611951Sslatteng /*---------------------------------------------------------
21711951Sslatteng * This routine sets the current character style.
21811951Sslatteng *
21911951Sslatteng * Results: None.
22011951Sslatteng *
22111951Sslatteng * Side Effects:
22211951Sslatteng * A new character style is output to the display.
22311951Sslatteng *---------------------------------------------------------
22411951Sslatteng */
22511951Sslatteng
22611951Sslatteng {
22711951Sslatteng GRsetcolor(fontmap[style]);
22811951Sslatteng }
22911951Sslatteng
GRsetlinestyle(style)23011951Sslatteng GRsetlinestyle(style)
23111951Sslatteng int style; /* New stipple pattern for lines. */
23211951Sslatteng
23311951Sslatteng /*---------------------------------------------------------
23411951Sslatteng * This routine sets the current line style.
23511951Sslatteng *
23611951Sslatteng * Results: None.
23711951Sslatteng *
23811951Sslatteng * Side Effects:
23911951Sslatteng * A new line style is output to the display.
24011951Sslatteng *---------------------------------------------------------
24111951Sslatteng */
24211951Sslatteng
24311951Sslatteng {
24411951Sslatteng char s[4];
24511951Sslatteng
24611951Sslatteng GRsetcolor(stylecolor[style]);
24711951Sslatteng
24811951Sslatteng #ifndef FASTIO
24911951Sslatteng GRchex(stipple[style], s, 2);
25011951Sslatteng fprintf(display, "1%sFF", s);
25111951Sslatteng #else
25211951Sslatteng putc('1', display);
25311951Sslatteng putc(stipple[style]&0377, display);
25411951Sslatteng putc(0377, display);
25511951Sslatteng #endif
25611951Sslatteng }
25711951Sslatteng
25811976Sslatteng
GRsetcharsize(size)25911951Sslatteng GRsetcharsize(size)
26011951Sslatteng int size; /* character size (1 - 4) */
26111951Sslatteng
26211951Sslatteng /*---------------------------------------------------------
26311951Sslatteng * This routine sets the character size in the display,
26411951Sslatteng * if necessary.
26511951Sslatteng *
26611951Sslatteng * Results: None.
26711951Sslatteng *
26811951Sslatteng * Side Effects:
26911951Sslatteng * If the current display character size isn't already equal to size,
27011951Sslatteng * then it is made so.
27111951Sslatteng *---------------------------------------------------------
27211951Sslatteng */
27311951Sslatteng
27411951Sslatteng {
27511951Sslatteng if (size == curcharsize) return;
27611951Sslatteng curcharsize = size;
27711951Sslatteng #ifndef FASTIO
27811951Sslatteng if (curcharsize == 4)
27911951Sslatteng {
28011951Sslatteng fputs("^270F18L",display);
28111951Sslatteng charxsize = 15;
28211951Sslatteng charysize = 24;
28311951Sslatteng descenders = 6;
28411951Sslatteng }
28511951Sslatteng else if (curcharsize == 3)
28611951Sslatteng {
28711951Sslatteng fputs("^250A0EL",display);
28811951Sslatteng charxsize = 10;
28911951Sslatteng charysize = 14;
29011951Sslatteng descenders = 2;
29111951Sslatteng }
29211951Sslatteng else if (curcharsize == 2)
29311951Sslatteng {
29411951Sslatteng fputs("^17070CL", display);
29511951Sslatteng charxsize = 8;
29611951Sslatteng charysize = 12;
29711951Sslatteng descenders = 3;
29811951Sslatteng }
29911951Sslatteng else
30011951Sslatteng {
30111951Sslatteng fputs("^15050BL", display);
30211951Sslatteng charxsize = 6;
30311951Sslatteng charysize = 7;
30411951Sslatteng descenders = 1;
30511951Sslatteng };
30611951Sslatteng #else
30711951Sslatteng if (curcharsize == 4)
30811951Sslatteng {
30911951Sslatteng fputs("^27\17\30L",display);
31011951Sslatteng charxsize = 15;
31111951Sslatteng charysize = 24;
31211951Sslatteng descenders = 6;
31311951Sslatteng }
31411951Sslatteng else if (curcharsize == 3)
31511951Sslatteng {
31611951Sslatteng fputs("^25\12\16L",display);
31711951Sslatteng charxsize = 10;
31811951Sslatteng charysize = 14;
31911951Sslatteng descenders = 2;
32011951Sslatteng }
32111951Sslatteng else if (curcharsize == 2)
32211951Sslatteng {
32311951Sslatteng fputs("^17\10\14L", display);
32411951Sslatteng charxsize = 8;
32511951Sslatteng charysize = 12;
32611951Sslatteng descenders = 3;
32711951Sslatteng }
32811951Sslatteng else
32911951Sslatteng {
33011951Sslatteng fputs("^15\6\7L", display);
33111951Sslatteng charxsize = 6;
33211951Sslatteng charysize = 7;
33311951Sslatteng descenders = 1;
33411951Sslatteng };
33511951Sslatteng #endif
33611951Sslatteng }
33711951Sslatteng
33811976Sslatteng
GRInit(stream,invert)33911951Sslatteng GRInit(stream, invert)
34011951Sslatteng FILE *stream; /* A pointer to the graphics display
34111951Sslatteng * file descriptor. The file must have
34211951Sslatteng * been opened by the caller.
34311951Sslatteng */
34411951Sslatteng int invert; /* An integer whose low-order eight bits
34511951Sslatteng * are ones iff the corresponding layers
34611951Sslatteng * are to be inverted (drawing means write
34711951Sslatteng * zeroes and erasing means write ones).
34811951Sslatteng */
34911951Sslatteng
35011951Sslatteng /*---------------------------------------------------------
35111951Sslatteng * GRInit initializes the graphics display and clears its screen.
35211951Sslatteng *
35311951Sslatteng * Results: None.
35411951Sslatteng *
35511951Sslatteng * Side Effects:
35611951Sslatteng * The display is re-initialized and the file is remembered for
35711951Sslatteng * use in all subsequent calls to this module. The display's
35811951Sslatteng * color map is reset. The display is put into raw mode, but
35911951Sslatteng * the previous mode bits are saved.
36011951Sslatteng *
36111951Sslatteng * Errors: None.
36211951Sslatteng *---------------------------------------------------------
36311951Sslatteng */
36411951Sslatteng
36511951Sslatteng {
36611951Sslatteng #ifdef FASTIO
36711976Sslatteng static int litout = LLITOUT;
36811951Sslatteng #endif
36911951Sslatteng static int ldisc = NTTYDISC;
37011951Sslatteng
37111951Sslatteng /* First, grab up the display modes, then reset them to put it
37211951Sslatteng * into cooked mode. Also, lock the terminal. If doing fast I/O
37311951Sslatteng * then set the LLITOUT bit. Note: setting the LLITOUT bit only
37411976Sslatteng * works if it happens before the stty. Also forces the display to
37511976Sslatteng * run at 9600 baud.
37611951Sslatteng */
37711951Sslatteng
37811951Sslatteng (void) ioctl(fileno(stream), TIOCSETD, (char *) &ldisc);
37911951Sslatteng (void) ioctl(fileno(stream), TIOCLGET, (char *) &localmode);
38011951Sslatteng #ifdef FASTIO
38111951Sslatteng (void) ioctl(fileno(stream), TIOCLBIS, (char *) &litout);
38211951Sslatteng #endif
38311951Sslatteng (void) gtty(fileno(stream), &sgttyb);
38411951Sslatteng sgflags = sgttyb.sg_flags;
38511976Sslatteng sgispeed = sgttyb.sg_ispeed;
38611976Sslatteng sgospeed = sgttyb.sg_ospeed;
38711951Sslatteng sgttyb.sg_flags = (sgttyb.sg_flags &
388*12240Sslatteng ~(RAW | CBREAK | ECHO | LCASE)) | EVENP | ODDP | CRMOD;
38911976Sslatteng sgttyb.sg_ispeed = B9600;
39011976Sslatteng sgttyb.sg_ospeed = B9600;
39111951Sslatteng (void) stty(fileno(stream), &sgttyb);
39211951Sslatteng (void) ioctl(fileno(stream), TIOCEXCL, (char *) &sgttyb);
39311951Sslatteng
39411951Sslatteng /* Save the file pointer around for later use, then output an
39511951Sslatteng * initialization string to the display. The initialization
39611951Sslatteng * string resets the terminal, sets formats, clears the display,
39711951Sslatteng * and initializes the read and write masks.
39811951Sslatteng */
39911951Sslatteng display = stream;
40011951Sslatteng setbuf(display, dbuf);
40111951Sslatteng #ifndef FASTIO
40211951Sslatteng GRchex(invert&0377, erase, 2);
40311951Sslatteng GRchex((~invert)&0377, draw, 2);
40411951Sslatteng fputs("\33\60", display);
40511951Sslatteng (void) fflush(display);
40611951Sslatteng (void) system("sleep 1");
40711951Sslatteng fprintf(display, "\33\33G1HDHN[%sLFF\14\33C%sM7FFFFFFF", erase, draw);
40811951Sslatteng fprintf(display, "c404022]+00002019001F02828");
40911951Sslatteng #else
41011951Sslatteng *erase = invert&0377;
41111951Sslatteng *draw = (~invert)&0377;
41211951Sslatteng fputs("\33\60", display);
41311951Sslatteng (void) fflush(display);
41411951Sslatteng (void) system("sleep 1");
41511951Sslatteng fputs("\33\33G18D8N[", display);
41611951Sslatteng putc(*erase, display);
41711951Sslatteng fputs("L\377\14\33C", display);
41811951Sslatteng putc(*draw, display);
41911951Sslatteng fputs("M\177\377\377\377c\100\100\42]+", display);
42011951Sslatteng putc('\0', display);
42111951Sslatteng putc('\0', display);
42211951Sslatteng fputs("2\01\220\01\360\50\50", display);
42311951Sslatteng #endif
42411951Sslatteng putc('3', display); /* Make sure the crosshair is off */
42511951Sslatteng putc('\0', display);
42611951Sslatteng curx = -1;
42711951Sslatteng cury = -1;
42811951Sslatteng curcharsize = -1;
42911951Sslatteng wmask = 0177;
43011951Sslatteng rmask = 0177;
43111951Sslatteng (void) fflush(display);
43211951Sslatteng }
43311951Sslatteng
43411976Sslatteng
GRClose()43511951Sslatteng GRClose()
43611951Sslatteng
43711951Sslatteng /*---------------------------------------------------------
43811951Sslatteng * GRClose does whatever is necessary to reset the characteristics
43911951Sslatteng * of the AED512 after the program is finished.
44011951Sslatteng *
44111951Sslatteng * Results: None.
44211951Sslatteng *
44311951Sslatteng * Side Effects:
44411951Sslatteng * The graphics display modes are reset.
44511951Sslatteng *---------------------------------------------------------
44611951Sslatteng */
44711951Sslatteng
44811951Sslatteng {
44911951Sslatteng sgttyb.sg_flags = sgflags;
45011951Sslatteng (void) stty(fileno(display), &sgttyb);
45111951Sslatteng (void) ioctl(fileno(display), TIOCNXCL, (char *) &sgttyb);
45211951Sslatteng (void) ioctl(fileno(display), TIOCLSET, (char *) &localmode);
45311951Sslatteng }
45411951Sslatteng
45511976Sslatteng
GRSetMap(pmap)45611951Sslatteng GRSetMap(pmap)
45711951Sslatteng char *pmap; /* A pointer to 256*3 bytes containing the
45811951Sslatteng * new values for the color map. The first
45911951Sslatteng * three values are red, green, and blue
46011951Sslatteng * intensities for color 0, and so on.
46111951Sslatteng */
46211951Sslatteng
46311951Sslatteng /*---------------------------------------------------------
46411951Sslatteng * GrSetMap outputs new values to the AED512 color map.
46511951Sslatteng *
46611951Sslatteng * Results: None.
46711951Sslatteng *
46811951Sslatteng * Side Effects:
46911951Sslatteng * The values in the color map are set from the array indicated
47011951Sslatteng * by pmap. The back1 and back2 strings are set so that the
47111951Sslatteng * routines GrBack1 and GrBack2 will switch the background color
47211951Sslatteng * to color 0 and color 256,respectively.
47311951Sslatteng *
47411951Sslatteng * Errors: None.
47511951Sslatteng *
47611951Sslatteng * (Modified from software written by John Ousterhout for the caesar
47711951Sslatteng * program)
47811951Sslatteng *---------------------------------------------------------
47911951Sslatteng */
48011951Sslatteng
48111951Sslatteng {
48211951Sslatteng char s[4], *p;
48311951Sslatteng int i;
48411951Sslatteng
48511951Sslatteng p = pmap;
48611951Sslatteng #ifndef FASTIO
48711951Sslatteng fputs("K0000", display);
48811951Sslatteng for (i = 0; i<256*3; ++i)
48911951Sslatteng {
49011951Sslatteng GRchex(*p++&0377, s, 2);
49111951Sslatteng fprintf(display, "%s", s);
49211951Sslatteng }
49311951Sslatteng #else
49411951Sslatteng putc('K', display);
49511951Sslatteng putc('\0', display);
49611951Sslatteng putc('\0', display);
49711951Sslatteng for (i = 0; i<256*3; ++i)
49811951Sslatteng {
49911951Sslatteng putc(*p++&0377, display);
50011951Sslatteng }
50111951Sslatteng #endif
50211951Sslatteng (void) fflush(display);
50311951Sslatteng
50411951Sslatteng }
50511951Sslatteng
506