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