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