| 1 | #ifndef lint | 
| 2 | static const char       RCSid[] = "$Id: aed.c,v 2.5 2003/08/20 10:00:09 schorsch Exp $"; | 
| 3 | #endif | 
| 4 | /* | 
| 5 | *  aed.c - driver for AED 512 terminal. | 
| 6 | */ | 
| 7 |  | 
| 8 | #include "copyright.h" | 
| 9 |  | 
| 10 | #include  <stdio.h> | 
| 11 |  | 
| 12 | #include  "rterror.h" | 
| 13 | #include  "color.h" | 
| 14 | #include  "driver.h" | 
| 15 |  | 
| 16 |  | 
| 17 | /* AED command characters */ | 
| 18 |  | 
| 19 | #define AEDFMT  "1888N" /* Format string to send to AED */ | 
| 20 | #define CSTAT   0100    /* Console status: lower case */ | 
| 21 | #define SCT     75      /* Set color lookup table */ | 
| 22 | #define SEC     67      /* Set color for vector drawing */ | 
| 23 | #define MOV     81      /* Set CAP (current access pointer) to x, y */ | 
| 24 | #define OPT     40      /* Miscellaneous terminal control */ | 
| 25 | #define SEN     71      /* Set encoding types */ | 
| 26 | #define RST     48      /* Reset terminal */ | 
| 27 | #define FFD     12      /* Clear screen */ | 
| 28 | #define EJC     85      /* Enable Joystick cursor positioning */ | 
| 29 | #define DJC     100     /* Disable Joystick cursor positioning */ | 
| 30 | #define SCC     99      /* Set Cursor Colors */ | 
| 31 | #define SCP     93      /* Set Cursor Parameters */ | 
| 32 | #define DFR     111     /* Draw Filled Rectangle */ | 
| 33 | #define RCP     106     /* Read Cursor Position */ | 
| 34 | #define ESC     27      /* Escape starts a command sequence */ | 
| 35 | #define SCS     96      /* Set Console Status */ | 
| 36 | #define END     1       /* Ctrl-A used to terminate command mode */ | 
| 37 |  | 
| 38 | #define BLK     0       /* color table entry for black */ | 
| 39 | #define WHT     7       /* color table entry for white */ | 
| 40 |  | 
| 41 | #define command(c)      (putc(ESC, stdout), putc(c, stdout)) | 
| 42 | #define byte(b)         putc(b, stdout) | 
| 43 | #define string(s)       fputs(s, stdout) | 
| 44 | #define flush()         fflush(stdout) | 
| 45 |  | 
| 46 | #define  GAMMA          2.5             /* exponent for color correction */ | 
| 47 |  | 
| 48 | #define  NCOLORS        248             /* our color table size */ | 
| 49 | #define  MINPIX         8               /* minimum hardware color */ | 
| 50 |  | 
| 51 | #define  NCOLS          512             /* maximum # columns for output */ | 
| 52 | #define  NROWS          483-COMHT       /* maximum # rows for output */ | 
| 53 | #define  COMHT          16              /* height of command line */ | 
| 54 | #define  COMCW          63              /* maximum chars on command line */ | 
| 55 |  | 
| 56 | static void aed_errout(char*); | 
| 57 | static void longwait(int t); | 
| 58 | static void aedgetcap(int  *xp, int *yp); | 
| 59 | static void aedsetcap(int  x, int y); | 
| 60 | static dr_newcolrf_t anewcolr; | 
| 61 | static void aedcoord(int  x, int y); | 
| 62 |  | 
| 63 | static dr_closef_t aed_close; | 
| 64 | static dr_clearf_t aed_clear; | 
| 65 | static dr_paintrf_t aed_paintr; | 
| 66 | static dr_getcurf_t aed_getcur; | 
| 67 | static dr_comoutf_t comout; | 
| 68 |  | 
| 69 | static struct driver  aed_driver = { | 
| 70 | aed_close, aed_clear, aed_paintr, aed_getcur, | 
| 71 | aed_comout, NULL, NULL, | 
| 72 | 1.0, NCOLS, NROWS | 
| 73 | }; | 
| 74 |  | 
| 75 |  | 
| 76 | struct driver * | 
| 77 | aed_init(name, id)                      /* open AED */ | 
| 78 | char  *name, *id; | 
| 79 | { | 
| 80 | if (ttyset(&aed_driver, fileno(stdin)) < 0) {   /* set tty driver */ | 
| 81 | eputs("cannot access terminal\n"); | 
| 82 | return(NULL); | 
| 83 | } | 
| 84 | command(RST);                                   /* reset AED */ | 
| 85 | longwait(2); | 
| 86 | command(OPT); | 
| 87 | byte(6); byte(1);                               /* AED command set */ | 
| 88 | command(SEN); | 
| 89 | string(AEDFMT); | 
| 90 | command(SCS);                                   /* set console status */ | 
| 91 | byte(CSTAT); | 
| 92 | command(SCC);                                   /* set cursor type */ | 
| 93 | byte(BLK); byte(WHT); byte(15); | 
| 94 | command(SCP); | 
| 95 | byte('+'); byte(0); byte(1); | 
| 96 | make_gmap(GAMMA);                               /* make color map */ | 
| 97 | erract[USER].pf =                               /* set error vector */ | 
| 98 | erract[SYSTEM].pf = | 
| 99 | erract[INTERNAL].pf = | 
| 100 | erract[CONSISTENCY].pf = aed_errout; | 
| 101 | erract[COMMAND].pf = aed_errout; | 
| 102 | if (erract[WARNING].pf != NULL) | 
| 103 | erract[WARNING].pf = aed_errout; | 
| 104 | return(&aed_driver); | 
| 105 | } | 
| 106 |  | 
| 107 |  | 
| 108 | static void | 
| 109 | aed_close(void)                                 /* close AED */ | 
| 110 | { | 
| 111 | erract[USER].pf =                       /* reset error vector */ | 
| 112 | erract[SYSTEM].pf = | 
| 113 | erract[INTERNAL].pf = | 
| 114 | erract[CONSISTENCY].pf = eputs; | 
| 115 | erract[COMMAND].pf = NULL; | 
| 116 | if (erract[WARNING].pf != NULL) | 
| 117 | erract[WARNING].pf = wputs; | 
| 118 | aedsetcap(0, 0);                        /* go to bottom */ | 
| 119 | command(SEC); | 
| 120 | byte(WHT);                              /* white text */ | 
| 121 | byte(END); | 
| 122 | byte('\n');                             /* scroll */ | 
| 123 | flush(); | 
| 124 | ttydone(); | 
| 125 | } | 
| 126 |  | 
| 127 |  | 
| 128 | static | 
| 129 | aed_clear(x, y)                                 /* clear AED */ | 
| 130 | int  x, y; | 
| 131 | { | 
| 132 | command(FFD); | 
| 133 | new_ctab(NCOLORS);                      /* init color table */ | 
| 134 | flush(); | 
| 135 | } | 
| 136 |  | 
| 137 |  | 
| 138 | static void | 
| 139 | aed_paintr(col, xmin, ymin, xmax, ymax)         /* paint a rectangle */ | 
| 140 | COLOR  col; | 
| 141 | int  xmin, ymin, xmax, ymax; | 
| 142 | { | 
| 143 | int  ndx; | 
| 144 |  | 
| 145 | ndx = get_pixel(col, anewcolr);         /* calls anewcolr() */ | 
| 146 | command(SEC);                           /* draw rectangle */ | 
| 147 | byte(ndx+MINPIX); | 
| 148 | aedsetcap(xmin, ymin+COMHT); | 
| 149 | command(DFR); | 
| 150 | aedcoord(xmax-1, ymax+(-1+COMHT)); | 
| 151 | flush(); | 
| 152 | } | 
| 153 |  | 
| 154 |  | 
| 155 | static int | 
| 156 | aed_getcur(xp, yp)                      /* get cursor position */ | 
| 157 | int  *xp, *yp; | 
| 158 | { | 
| 159 | int  com; | 
| 160 |  | 
| 161 | command(EJC);                   /* enable cursor */ | 
| 162 | com = getch();                  /* get key */ | 
| 163 | command(DJC);                   /* disable cursor */ | 
| 164 | aedgetcap(xp, yp);              /* get cursor position */ | 
| 165 | *yp -= COMHT;                   /* convert coordinates */ | 
| 166 | return(com);                    /* return key hit */ | 
| 167 | } | 
| 168 |  | 
| 169 |  | 
| 170 | static void | 
| 171 | aed_comout(out)                         /* output to command line */ | 
| 172 | register char  *out; | 
| 173 | { | 
| 174 | static int  newl = 1; | 
| 175 | static int  inmsg = 0; | 
| 176 |  | 
| 177 | while (*out) { | 
| 178 | if (newl) {                     /* new line */ | 
| 179 | command(SEC); | 
| 180 | byte(BLK); | 
| 181 | aedsetcap(0, 0); | 
| 182 | command(DFR); | 
| 183 | aedcoord(NCOLS-1, COMHT-1); | 
| 184 | aedsetcap(1, 4); | 
| 185 | command(SEC);           /* white text */ | 
| 186 | byte(WHT); | 
| 187 | byte(END); | 
| 188 | newl = 0; | 
| 189 | } | 
| 190 | switch (*out) { | 
| 191 | case '\n':                      /* end of line */ | 
| 192 | newl = 1; | 
| 193 | /* fall through */ | 
| 194 | case '\r': | 
| 195 | inmsg = 0; | 
| 196 | byte('\r'); | 
| 197 | break; | 
| 198 | case '\b':                      /* back space */ | 
| 199 | if (inmsg > 0 && --inmsg < COMCW) | 
| 200 | byte('\b'); | 
| 201 | break; | 
| 202 | default:                        /* character */ | 
| 203 | if (inmsg++ < COMCW) | 
| 204 | byte(*out); | 
| 205 | break; | 
| 206 | } | 
| 207 | out++; | 
| 208 | } | 
| 209 | flush(); | 
| 210 | } | 
| 211 |  | 
| 212 |  | 
| 213 | static void | 
| 214 | aed_errout(msg)                         /* print an error message */ | 
| 215 | char  *msg; | 
| 216 | { | 
| 217 | aed_comout(msg); | 
| 218 | if (*msg && msg[strlen(msg)-1] == '\n') | 
| 219 | longwait(2); | 
| 220 | } | 
| 221 |  | 
| 222 |  | 
| 223 | /* | 
| 224 | * aedsetcap - sets AED's current access pointer to (x, y). | 
| 225 | */ | 
| 226 |  | 
| 227 | static void | 
| 228 | aedsetcap(x, y) | 
| 229 | register int  x, y; | 
| 230 | { | 
| 231 | command(MOV); | 
| 232 | aedcoord(x, y); | 
| 233 | } | 
| 234 |  | 
| 235 | /* | 
| 236 | * aedcoord - puts out an (x, y) coordinate in AED 8 bit format. | 
| 237 | */ | 
| 238 |  | 
| 239 | static void | 
| 240 | aedcoord(x, y) | 
| 241 | register int  x, y; | 
| 242 | { | 
| 243 | byte(((x >> 4) & 0x30) | ((y >> 8) & 0x3)); | 
| 244 | byte(x & 0xff); | 
| 245 | byte(y & 0xff); | 
| 246 | } | 
| 247 |  | 
| 248 |  | 
| 249 | static void | 
| 250 | aedgetcap(xp, yp)               /* get cursor postion */ | 
| 251 | int  *xp, *yp; | 
| 252 | { | 
| 253 | register int  c; | 
| 254 | /* get cursor postition */ | 
| 255 | command(RCP); | 
| 256 | flush(); | 
| 257 | c = getch(); | 
| 258 | *xp = (c & 0x30) << 4; | 
| 259 | *yp = (c & 0x3) << 8; | 
| 260 | *xp |= getch(); | 
| 261 | *yp |= getch(); | 
| 262 | } | 
| 263 |  | 
| 264 |  | 
| 265 | static void | 
| 266 | anewcolr(index, r, g, b)                /* enter a color into our table */ | 
| 267 | int  index; | 
| 268 | int  r, g, b; | 
| 269 | { | 
| 270 | command(SCT); | 
| 271 | byte((index+MINPIX)&255); | 
| 272 | byte(1); | 
| 273 | byte(r); | 
| 274 | byte(g); | 
| 275 | byte(b); | 
| 276 | flush(); | 
| 277 | } | 
| 278 |  | 
| 279 |  | 
| 280 | static void | 
| 281 | longwait(t)             /* longer wait */ | 
| 282 | int  t; | 
| 283 | { | 
| 284 | flush(); | 
| 285 | sleep(t); | 
| 286 | } |