r109: reorganized header files
[ctsim.git] / libctgraphics / sgpdrive.cpp
1 /*****************************************************************************
2 **  This is part of the CTSim program
3 **  Copyright (C) 1983-2000 Kevin Rosenberg
4 **
5 **  $Id: sgpdrive.cpp,v 1.3 2000/06/19 19:04:05 kevin Exp $
6 **
7 **  This program is free software; you can redistribute it and/or modify
8 **  it under the terms of the GNU General Public License (version 2) as
9 **  published by the Free Software Foundation.
10 **
11 **  This program is distributed in the hope that it will be useful,
12 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 **  GNU General Public License for more details.
15 **
16 **  You should have received a copy of the GNU General Public License
17 **  along with this program; if not, write to the Free Software
18 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 ******************************************************************************/
20
21 /* Device Driver for IBM PC Kevin Rosenberg  March 84 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <math.h>
26 #include "ctsupport.h"
27 #include "sgp.h"
28
29
30 static int init_prt(void);
31 static void term_prt(void);
32
33 /*===========================================================*/
34 /* fundamental device drivers                                */
35 /*===========================================================*/
36
37 #define XCHARSIZ        (1.0 / 80.0)            /* size of standard characters */
38 #define YCHARSIZ        (1.0 / 25.0)            /* on screen in NDC */
39
40 #define CRTASPT     (0.75)                      /* for IBM ECD */
41
42 /*-------------------*/
43 /* print buffer data */
44 /*-------------------*/
45 #define PRTINIT     1
46 #define PRTLIN      2
47 #define PRTTERM     3
48
49 #define PRTSIZE    200
50 #define PRTMODE    1                    /* Epson 120 dot/in graphic mode */
51 #define PRTASPT   (120.0 / 72.0)        /* dots/in vectical / horizontal */
52
53 static DEVICE crt, prt;
54 CHARSPEC cspec;
55 static GRFSTATE state;
56
57
58
59 /* NAME
60  *   gp_init            Initialize graphics package
61  *
62  * SYNOPSIS
63  *   gp_init()
64  */
65
66
67 int
68 _sgp2_init_dev (SGP_ID cwin)
69 {
70 #if 0
71     initdevice (CRTDEV, GM_ENHANCED, 0, 0);
72     initdevice (PRTDEV, PRTMODE, (int) (PRTSIZE * PRTASPT), PRTSIZE);
73     opendevice (CRTDEV);
74     setlinestyle (LS_SOLID);
75     setcolor (1);
76     _sgp2_set_text (XCHARSIZ, YCHARSIZ, 0.0, 0);
77     setbackg (0);
78     settextclr (1, 0);
79     gp_set_aspect (CRTDEV, CRTASPT);
80     gp_set_aspect (PRTDEV, 1.0);
81 #endif
82
83     state.xndc = 10.;           /* to guarntee a move */
84     _sgp2_stylus (cwin, 0.0,0.0,0);             /* move to starting corner */
85
86     return (TRUE);
87 }
88
89
90 /* NAME
91  *   gp_initdev         Initializes graphic device
92  *
93  * SYNOPSIS
94  *   initdevice (dev, mode, xsize, ysize)
95  *   int dev            Device handle
96  *   int mode           Mode for device (device specific)
97  *   int xsize          Size of x buffer for PRTDEV
98  *   int ysize          Size of y buffer for PRTDEV
99  */
100
101 int 
102 initdevice (int dev, int mode, int xsize, int ysize)
103 {
104     if (dev & CRTDEV)
105         {
106             //       crt.dotfunc = crt_wdot;
107             //      crt.linefunc = crt_line;
108             crt.xmin = 0;
109             crt.ymin = 0;
110             switch (crt.mode)
111                 {
112 #if 0
113                 case 4:
114                 case 5: 
115                     crt.xmax  = 319;
116                     crt.xsize = 320;
117                     crt.ymax  = 199;
118                     crt.ysize = 200;
119                     crt.colormax = 3;
120                     break;
121                 case GM_640x200:
122                     crt.xmax  = 639;
123                     crt.xsize = 640;
124                     crt.ymax  = 199;
125                     crt.ysize = 200;
126                     crt.colormax = 1;
127                     break;
128                 case GM_ENHANCED:
129                 case GM_MONOGRF:
130                     crt.xmax  = 639;
131                     crt.xsize = 640;
132                     crt.ymax  = 349;
133                     crt.ysize = 350;
134                     crt.colormax = 15;
135                     break;
136                 case GM_640x480x16:
137                     crt.xmax  = 639;
138                     crt.xsize = 640;
139                     crt.ymax  = 479;
140                     crt.ysize = 480;
141                     crt.colormax = 15;
142                     break;
143                 case GM_640x480x256:
144                     crt.xmax  = 639;
145                     crt.xsize = 640;
146                     crt.ymax  = 479;
147                     crt.ysize = 480;
148                     crt.colormax = 255;
149                     break;
150                 case GM_1024x768x16:
151                     crt.xmax  = 1023;
152                     crt.xsize = 1024;
153                     crt.ymax  = 767;
154                     crt.ysize = 768;
155                     crt.colormax = 15;
156                     break;
157                 case GM_1024x768x256:
158                     crt.xmax  = 1023;
159                     crt.xsize = 1024;
160                     crt.ymax  = 767;
161                     crt.ysize = 768;
162                     crt.colormax = 255;
163                     break;
164 #endif
165                 default:
166                     return (FALSE);
167                 }
168             //      crt_set_mode (crt.mode, TRUE);      /* Initialize device */
169         }
170
171     if (dev & PRTDEV) {
172         if (prt.open == TRUE)
173             closedevice (PRTDEV);
174         prt.buf = NULL;
175         if (mode < 0)
176             prt.mode = PRTMODE;
177         if (mode > 6)
178             prt.mode = PRTMODE;
179         else
180             prt.mode = mode;
181
182         if (xsize > 1 && ysize > 1) {
183             prt.xsize = xsize;
184             prt.ysize = ysize;
185             prt.xmin = 0;
186             prt.ymin = 0;
187             prt.xmax = prt.xsize - 1;
188             prt.ymax = prt.ysize - 1;
189         }
190
191         prt.colormax = 1;
192         //          prt.dotfunc = prtdot;
193         //          prt.linefunc = prtline;
194
195         init_prt ();            /* Initialize the device */
196     }
197
198     return (TRUE);
199 }
200             
201
202 /* NAME
203  *    gp_opendev                Open device for output
204  *
205  * SYNOPSIS
206  *    gp_opendev (dev)
207  *    int dev                   Device handle
208  *                              devices are number in powers of two
209  */
210
211 int 
212 opendevice (int dev)
213 {
214     if (dev & CRTDEV)
215         crt.open = TRUE;
216
217     if (dev & PRTDEV)
218         prt.open = TRUE;
219
220     return(TRUE);
221 }
222
223
224 /* NAME
225  *   gp_closedev                Close device for output
226  *
227  * SYNOPSIS
228  *   gp_closedev (dev)
229  *   int dev                    Device handle
230  *
231  * DESCRIPTION
232  *    Temporarily suspends output from going to a device
233  */
234
235 void
236 closedevice (int dev)
237 {
238     if (dev & CRTDEV)           /* close crt */
239         crt.open = FALSE;
240
241     if (dev & PRTDEV)
242         prt.open = FALSE;
243 }
244
245
246 void
247 termdevice (int dev)
248 {
249     if (dev & PRTDEV)
250         term_prt ();
251 }
252
253 static int init_prt(void)
254 {
255     return(0);
256 }
257
258
259 static void term_prt(void)
260 {
261 }
262
263 /*===========================================================*/
264 /* stylus draws a line to the absolute point x,y in NDC's    */
265 /*              t=0 for move, t=1 for draw                   */
266 /*===========================================================*/
267 void 
268 _sgp2_stylus (SGP_ID cwin, double x, double y, int beam)
269 {
270     int xp, yp;
271
272     if ((state.xndc == x) && (state.yndc == y) && (beam == 0))
273         return;         /* no need to move */
274
275     state.xndc = x;             /* save current beam location */
276     state.yndc = y;
277
278     if (cwin != NULL) {
279         xp = (int) (x * cwin->pw_xsize + 0.5);
280         yp = (int) (y * cwin->pw_ysize + 0.5);
281 #if HAVE_G2_H
282         if (beam != 0)
283             g2_line (cwin->g2_id, (double) cwin->phys_curx, (double) cwin->phys_cury, (double) xp, (double) yp);
284 #endif
285         cwin->phys_curx = xp;
286         cwin->phys_cury = yp;
287     }
288 }
289
290 void
291 pntndc (SGP_ID cwin, double x, double y)
292 {
293     _sgp2_stylus (cwin, x, y, 0);       /* move to point */
294     //  if (crt.open == TRUE)
295     //      cpix_set (crt.icurx, crt.icury, crt.color);
296 }
297         
298 void
299 markndc (SGP_ID cwin, double x, double y)
300 {
301     _sgp2_stylus (cwin, x, y, 0);       /* move to point */
302
303     if (crt.open == TRUE)
304         wrtsymbol (state.marktype, crt.icurx, crt.icury, &crt);
305
306     if (prt.open == TRUE)
307         wrtsymbol (state.marktype, prt.icurx, prt.icury, &prt);
308 }
309
310 GRFSTATE *
311 inqstate (void)
312 {
313     return (&state);
314 }
315
316 void
317 gp_set_aspect (int dev, double asp)
318 {
319     if (asp > 0.0) {
320         if (dev & CRTDEV)
321             crt.asp = asp;
322         if (dev & PRTDEV)
323             prt.asp = asp;
324     }
325 }
326
327 void 
328 setlinestyle (int style)
329 {
330     if (style == state.linestyle)
331         return;
332
333     state.linestyle = style;
334
335     crt.style = style;
336     prt.style = style;
337
338     //  crt_line_style (crt.style);
339 }
340
341 void
342 setlinewidth (int wid)
343 {
344     state.linewidth = wid;
345 }
346
347 DEVICE *
348 inqdev (int dev)
349 {
350     if (dev & CRTDEV)
351         return (&crt);
352     else if (dev & PRTDEV)
353         return (&prt);
354     else
355         return (NULL);
356 }
357
358 /*===========================================================*/
359 /* set text size                                             */
360 /*===========================================================*/
361 void
362 _sgp2_set_text ( SGP_ID cwin,
363          double width,
364          double height,                 /* size of character in NDC */
365          double textangle,                      /* text angle */
366          int font                               /* text font */
367          )
368 {
369     double temp;
370
371 #if HAVE_G2_H
372     g2_set_font_size(cwin->g2_id, (height * cwin->pw_ysize));
373 #endif
374     height = clamp (height, 0.0, 1.0);
375     width = clamp (width, 0.0, 1.0);
376     /*  textangle = textangle - (2 * PI * (int) (textangle / (2 * PI)));
377      */
378     cspec.width = width;
379     cspec.height = height;
380     cspec.textangle = textangle;
381     cspec.font = font;
382
383     if (textangle > - HALFPI / 2 && textangle < HALFPI / 2) {
384         cspec.updir = YPLUS;
385         cspec.textdir = XPLUS;
386     } else if (textangle > HALFPI / 2 && textangle < 3 * HALFPI / 2) {
387         cspec.updir = XMINUS;
388         cspec.textdir = YPLUS;
389     } else if (textangle > 3 * HALFPI / 2 && textangle < 5 * HALFPI / 2) {
390         cspec.updir = YMINUS;
391         cspec.textdir = XMINUS;
392     } else if (textangle > 5 * HALFPI / 2 && textangle < 7 * HALFPI / 2) {
393         cspec.updir = XPLUS;
394         cspec.textdir = YMINUS;
395     } else {
396         cspec.updir = YPLUS;
397         cspec.textdir = XPLUS;
398     }
399
400     if (cspec.updir == XMINUS || cspec.updir == XPLUS) {
401         temp = height;
402         height = width;
403         width = temp;
404     }
405
406     crt.icwidth = (int) (width * crt.xsize + 0.5);
407     crt.icheight = (int) (height * crt.ysize + 0.5);
408     crt.icwidth = clamp (crt.icwidth, 8, crt.xsize);
409     crt.icheight = clamp (crt.icheight, 8, crt.ysize);
410
411     prt.icwidth = (int) (width * prt.xsize + 0.5);
412     prt.icheight = (int) (height * prt.ysize + 0.5);
413     prt.icwidth = clamp (prt.icwidth, 8, prt.xsize);
414     prt.icheight = clamp (prt.icheight, 8, prt.ysize);
415 }
416
417 void
418 settextclr (int fore, int back)
419 {
420     cspec.fore = fore;
421     cspec.back = back;
422     crt.cfore = fore;
423     crt.cback = back;
424     prt.cfore = clamp (fore, 0, prt.colormax);
425     prt.cback = back;
426 }
427
428 void
429 setcolor (int fore)
430 {
431     int back;
432
433     state.foregnd = fore;
434     back = state.backgnd;
435     crtcolor (crt.mode, &fore, &back);          /* set colors on crt */
436     crt.color = fore;
437     prt.color = clamp (fore, 0, prt.colormax);
438 }
439
440 void
441 setbackg (int back)
442 {
443     int fore;
444
445     state.backgnd = back;
446     fore = state.foregnd;
447     crtcolor (crt.mode, &fore, &back);
448 }
449
450 /*
451  * INITMARKER (<SYMBOL>)
452  *
453  * Sets the current marker symbol (cross, square, diamond..)
454  */
455 int 
456 initmarker (int marker, int color)
457 {
458     if (marker > NMARKERS || marker < 0)
459         return(-1);
460     else {
461         state.marktype = marker;
462         state.markcolor = color;
463     }
464     return(0);
465 } /* end initmarker */
466
467 /*
468  * SETCHARDIR ( <DIRECTION> )
469  *
470  * indicates in which direction a string should be printed, e.g.:
471  *  direction = YPLUS  -> print on the horizontal from left to right
472  *  direction = YMINUS -> print upside-down characters from right to left
473  *  direction = XMINUS -> print on the vertical from down to up
474  *  direction = XPLUS  -> print on the vertical from up to down
475  */
476 int 
477 settextdir (
478             int direction        /* direction flag */
479             )
480 {
481
482     if (direction != XPLUS &&
483         direction != XMINUS &&
484         direction != YPLUS &&
485         direction != YMINUS ) {
486         printf("Error in character direction: %d\n", direction);
487         return(-1);
488     }
489     cspec.textdir = direction;
490     charsize (cspec.width, cspec.height);
491
492     return(0);
493 }  /* end setchardir */
494
495
496 void
497 _sgp2_dev_text (SGP_ID cwin, char *message)
498 {
499 #if HAVE_G2_H
500     g2_string (cwin->g2_id, cwin->phys_curx, cwin->phys_cury, message);
501 #endif
502 }
503
504 /*===========================================================*/
505 /* terminate graphics to current device                      */
506 /*     close any files, and output any buffers               */
507 /*===========================================================*/
508 void
509 termgrf2 (void)
510 {
511     if (prt.open == TRUE) {
512         flushdevice (PRTDEV);
513         closedevice (PRTDEV);
514         termdevice (PRTDEV);
515     }
516
517     if (crt.open == TRUE) {
518         closedevice (CRTDEV);
519     }   
520 }
521
522
523 void
524 flushdevice (int dev)
525 {
526     // if (dev & PRTDEV)
527     //      prtline (PRTTERM, 0, 0, 0, 0, 0, 0);   /*  print contents of printer buffer */
528 }