1 /**
2  ** BCC2GRX  -  Interfacing Borland based graphics programs to LIBGRX
3  ** Copyright (C) 1993-97 by Hartmut Schirmer
4  **
5  **
6  ** Contact :                Hartmut Schirmer
7  **                          Feldstrasse 118
8  **                  D-24105 Kiel
9  **                          Germany
10  **
11  ** e-mail : hsc@techfak.uni-kiel.de
12  **
13  ** This file is part of the GRX graphics library.
14  **
15  ** The GRX graphics library is free software; you can redistribute it
16  ** and/or modify it under some conditions; see the "copying.grx" file
17  ** for details.
18  **
19  ** This library is distributed in the hope that it will be useful,
20  ** but WITHOUT ANY WARRANTY; without even the implied warranty of
21  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
22  **
23  **/
24 
25 #define __BCCGRX_C
26 
27 #include "bccgrx00.h"
28 
29 #define MAX_MODES 256
30 
31 /* ----------------------------------------------------------------- */
32 
33 static char copyright[]="Copyright (C) 1993-1994  Hartmut Schirmer";
34 int           __gr_Mode = 0;                    /* actual graphics mode     */
35 int           __gr_INIT = FALSE;                /* TRUE after initgraph()   */
36 char          __gr_BGICHR[128];                 /* Path to .chr files       */
37 int           __gr_MaxMode = 0;                 /* Last available mode      */
38 int           __gr_Result = grOk;               /* stores error code        */
39 int           __gr_X, __gr_Y;                   /* graphics cursor pos      */
40 int           __gr_vpl, __gr_vpt,               /* actual viewport          */
41 	      __gr_vpr, __gr_vpb;
42 int           __gr_color;                       /* drawing color            */
43 int           __gr_colorbg;                     /* background color         */
44 int           __gr_colorfill;                   /* fill color               */
45 GrColor       __gr_WR = GrWRITE;                /* Write mode               */
46 int           __gr_lstyle = SOLID_LINE;         /* Actual line style        */
47 int           __gr_fpatno = SOLID_FILL;         /* Actual filling pattern   */
48 int           __gr_Xasp = 10000;                /* Aspect ratio             */
49 int           __gr_Yasp = 10000;
50 int           __gr_clip = TRUE;                 /* actual clipping state    */
51 
52 int           __gr_Y_page_offs = 0;             /* Y offset for page simulation */
53 
54 int           __gr_ADAPTER = GR_VGA;            /* Adapter used             */
55 int           __gr_TextLineStyle = 0;           /* use setlinestyle() while
56 						   plotting .chr fonts      */
57 
58 int          (*__gr_initgraph_hook)(void)=NULL;  /* hook for overriding mode */
59                                                 /* setting in initgraph     */
60 int          (*__gr_closegraph_hook)(void)=NULL;
61 
62 GrPattern      __gr_fillpattern;                /* GRX filling settings     */
63 GrLineOption   __gr_Line;                       /* GRX line settings        */
64 
65 unsigned char __gr_fpatterns[][8] = {     /* BGI fill patterns        */
66   { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},   /* EMPTY_FILL        */
67   { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},   /* SOLID_FILL        */
68   { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00},   /* LINE_FILL         */
69   { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80},   /* LTSLASH_FILL      */
70   { 0xE0, 0xC1, 0x83, 0x07, 0x0E, 0x1C, 0x38, 0x70},   /* SLASH_FILL        */
71   { 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x87, 0xC3, 0xE1},   /* BKSLASH_FILL      */
72   { 0xA5, 0xD2, 0x69, 0xB4, 0x5A, 0x2D, 0x96, 0x4B},   /* LTBKSLASH_FILL    */
73   { 0xFF, 0x88, 0x88, 0x88, 0xFF, 0x88, 0x88, 0x88},   /* HATCH_FILL        */
74   { 0x81, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x81},   /* XHATCH_FILL       */
75   { 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33, 0xCC, 0x33},   /* INTERLEAVE_FILL   */
76   { 0x80, 0x00, 0x08, 0x00, 0x80, 0x00, 0x08, 0x00},   /* WIDE_DOT_FILL     */
77   { 0x88, 0x00, 0x22, 0x00, 0x88, 0x00, 0x22, 0x00},   /* CLOSE_DOT_FILL    */
78   { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}    /* USER_FILL         */
79 };
80 
81 #ifdef GRX_VERSION
82 int __gr_BGI_p = 1;   /* requested / available # of pages  (valid: 1,2) */
83 #endif
84 int __gr_BGI_w = 640; /* resulution and colors needed to emulate        */
85 int __gr_BGI_h = 480; /* BGI driver modes                               */
86 int __gr_BGI_c = 16;  /* default : Standard VGA                         */
87 
88 
89 #ifdef __GNUC__
90 #define NULL_IS_EMPTY(s) ((s) ? : "")
91 #else
92 #define NULL_IS_EMPTY(s) ((s) ? (s) : "")
93 #endif
94 
95 /* ----------------------------------------------------------------- */
96 
97 GraphicsMode *__gr_Modes = NULL;
98 
ModeCompare(GraphicsMode * a,GraphicsMode * b)99 static int ModeCompare(GraphicsMode *a, GraphicsMode *b) {
100   int size_a, size_b;
101   if (a->colors < b->colors) return -1;
102   if (a->colors > b->colors) return +1;
103   size_a = a->width * a->height;
104   size_b = b->width * b->height;
105   if (size_a < size_b) return -1;
106   if (size_a > size_b) return +1;
107   if (a->width < b->width) return -1;
108   if (a->width > b->width) return +1;
109   return 0;
110 }
111 
NewMode(int w,int h,long c)112 static void NewMode(int w, int h, long c) {
113   GraphicsMode *p, *q, *qn;
114   p = malloc(sizeof(GraphicsMode));
115   if (p != NULL) {
116     p->width = w;
117     p->height = h;
118     p->colors = c;
119     p->next = NULL;
120     if (__gr_Modes == NULL) {
121       __gr_Modes = p;
122       return;
123     }
124     switch(ModeCompare(p,__gr_Modes)) {
125       case -1 : /* p < __gr_Modes */
126 		p->next = __gr_Modes;
127 		__gr_Modes = p;
128 		return;
129       case  0 : /* p == __gr_Modes */
130 		free(p);
131 		return;
132     }
133     q = __gr_Modes;
134     while ((qn=q->next) != NULL) {
135       switch (ModeCompare(p,qn)) {
136 	case -1 : /* p < q->next */
137 		  p->next = qn;
138 		  q->next = p;
139 		  return;
140 	case  0 : /* p == q->next */
141 		  free(p);
142 		  return;
143       }
144       q = q->next;
145     }
146     /* append to end */
147     p->next = q->next;
148     q->next = p;
149   }
150 }
151 
__gr_getmode_whc(int mode,int * w,int * h,long * c)152 int __gr_getmode_whc(int mode, int *w, int *h, long *c) {
153   GraphicsMode *p;
154   p = __gr_Modes;
155   mode -= __FIRST_DRIVER_SPECIFIC_MODE;
156   if (mode < 0)
157     return FALSE;
158   while (p != NULL && mode-->0)
159     p = p->next;
160   if (p==NULL) return FALSE;
161   *w = p->width;
162   *h = p->height;
163   *c = p->colors;
164   return TRUE;
165 }
166 
167 #ifdef GRX_VERSION
168 
169   /* ---- GRX v2.0 */
build_mode_table(void)170   static void build_mode_table(void) {
171     GrFrameMode fmode;
172     const GrVideoMode *mp;
173     char ubpp;
174 
175     for (fmode = GR_firstGraphicsFrameMode;
176 	   fmode <= GR_lastGraphicsFrameMode;
177 	     ++fmode ) {
178       mp = GrFirstVideoMode(fmode);
179       while (mp != NULL) {
180 	ubpp = mp->bpp;
181 	if(ubpp > 24) ubpp = 24;
182 #if defined(__TURBOC__) && defined(__MSDOS__)
183 	if(ubpp < 15)
184 #endif
185 	NewMode(mp->width, mp->height, 1L << ubpp);
186 	mp = GrNextVideoMode(mp);
187       }
188     }
189   }
190 
191   #define COLOR_NR2DRV(col) (col)
192 
193 #else
194 
195   /* ---- GRX v1.0x */
196   #ifdef GR_DRV_VER_GRD
197   #define _GRD GR_DRV_VER_GRD
198   #define _GRN GR_DRV_VER_GRN
199   #define _VDR GR_DRV_VER_VDR
200   #endif
201 
COLOR_NR2DRV(int col)202   static long COLOR_NR2DRV(int col) {
203     switch (col) {
204       case 1<<16 : return 0xC010;
205       case 1<<24 : return 0xC018;
206     }
207     return col;
208   }
209 
COLOR_DRV2NR(int c)210   static long COLOR_DRV2NR(int c) {
211     if ( (c & 0xC000) == 0xC000)
212       c = 1<<(c & 0x00ff);
213     return c;
214   }
215 
color_ok(long c)216   static int color_ok(long c) {
217     /* Check if GRX supports requested color mode */
218     int old_colors, res;
219     extern int _GrNumColors;  /* happy hacking ... */
220     c = COLOR_DRV2NR(c);
221     switch (c) {
222       case 1<<15 :
223       case 1<<16 :
224       case 1<<24 : old_colors = _GrNumColors;
225 		   _GrNumColors = c;
226 		   res = GrLineOffset(128) != 0;
227 		   _GrNumColors = old_colors;
228 		   return res;
229     }
230     return TRUE; /* No way to check other colors ... */
231   }
232 
233   #ifdef _VDR
234   static int driver = _GRD;
235   #endif
236 
CheckTableEntry(GR_DRIVER_MODE_ENTRY * gm)237   static int CheckTableEntry(GR_DRIVER_MODE_ENTRY *gm) {
238     if (gm == NULL) return FALSE;
239     if (!color_ok(gm->number_of_colors) )
240       return FALSE;
241     #ifdef _VDR
242       if (driver == _VDR)
243 	return gm->mode.vdr.BIOS_mode != 0xFFF;
244       if (driver == _GRN)
245 	return gm->mode.grn.BIOS_mode != 0xFF;
246       return FALSE;
247     #else
248       return gm->BIOS_mode != 0xFF;
249     #endif
250   }
251 
build_mode_table(void)252   static void build_mode_table(void) {
253     GR_DRIVER_MODE_ENTRY *tm, *gm;
254     #ifdef _VDR
255     driver = 0xFFFF0000 &
256     #endif
257     GrGetDriverModes(&tm, &gm);
258 
259     while (gm->width != 0 && gm->height != 0 && gm->number_of_colors != 0) {
260       if (CheckTableEntry(gm))
261 	NewMode(gm->width, gm->height, COLOR_DRV2NR(gm->number_of_colors));
262       ++gm;
263     }
264   }
265 
266 #endif
267 
268 /* ----------------------------------------------------------------- */
269 
__gr_set_up_modes(void)270 void __gr_set_up_modes(void)
271 {
272   int mode;
273   GraphicsMode *p;
274   static int DidInit = FALSE;
275 
276   if (DidInit) return;
277   if (strlen(copyright) != sizeof(copyright)-1)
278     ; // exit(1);
279 # ifdef __linux__
280    /* vga_init(); */
281 # endif
282   MM = 1;
283   GrSetMode( GrCurrentMode());                       /* Init grx */
284   __gr_ADAPTER = GrAdapterType();
285   if (__gr_ADAPTER == GR_S3)
286     __gr_ADAPTER = GR_VGA;
287   build_mode_table();
288   p = __gr_Modes;
289   mode = __FIRST_DRIVER_SPECIFIC_MODE-1;
290   while (p != NULL) {
291     ++mode;
292     p = p->next;
293   }
294   MM = mode;
295   DidInit = TRUE;
296 }
297 
298 /* ----------------------------------------------------------------- */
299 
__gr_White(void)300 int __gr_White(void) {
301   return GrNumColors() > 256 ? GrWhite() : 15;
302 }
303 
getmaxx(void)304 int getmaxx(void) {
305   return GrScreenX()-1;
306 }
307 
getmaxy(void)308 int getmaxy(void) {
309   return GrScreenY()-1;
310 }
311 
312 /* ----------------------------------------------------------------- */
graphdefaults(void)313 void graphdefaults(void)
314 {
315   ERR          = grOk;
316   moveto( 0, 0);
317   COL = FILL   = WHITE;
318   COLBG        = BLACK;
319   __gr_WR      = GrWRITE;
320 
321   _DO_INIT_CHECK;
322   GrSetContext( NULL);         /* ViewPort == Full screen */
323 #ifdef GRX_VERSION
324   GrSetViewport(0,0);
325   PY = 0;
326 #endif
327   VL = VT = 0;
328   VR = getmaxx();
329   VB = getmaxy();
330   __gr_clip = TRUE;
331 
332   __gr_Xasp = 10000;
333   __gr_Yasp = __gr_Xasp * ((VR+1)*3L) / ((VB+1)*4L);
334 
335   __gr_lstyle     = SOLID_LINE;
336   LNE.lno_pattlen = 0;
337   LNE.lno_dashpat = NULL;
338   LNE.lno_width   = 1;
339 
340   FPATT = SOLID_FILL;
341   FILLP.gp_ispixmap    = 0;    /* Bitmap fill pattern */
342   FILLP.gp_bmp_data    = (unsigned char *)&__gr_fpatterns[FPATT];
343   FILLP.gp_bmp_height  = 8;
344   FILLP.gp_bmp_fgcolor = COL;
345   FILLP.gp_bmp_bgcolor = COLBG;
346 
347   __gr_TextLineStyle = 0;
348 }
349 
350 /* ----------------------------------------------------------------- */
351 
__gr_adaptcnv(int grx)352 int __gr_adaptcnv(int grx) {
353   switch (grx) {
354     case GR_VGA   : return VGA;
355     case GR_EGA   : return EGA;
356     case GR_8514A : return IBM8514;
357     case GR_HERC  : return HERCMONO;
358   }
359   return grx;
360 }
361 
362 /* ----------------------------------------------------------------- */
setgraphmode(int mode)363 void setgraphmode(int mode)
364 {
365   int w, h;
366   long c;
367 
368   _DO_INIT_CHECK;
369   switch (mode) {
370     case GRX_DEFAULT_GRAPHICS:
371 #ifdef GRX_VERSION
372       w = GrDriverInfo->defgw;
373       h = GrDriverInfo->defgh;
374       c = GrDriverInfo->defgc;
375       goto Default;
376 #else
377       GrSetMode( GR_default_graphics);
378       break;
379 #endif
380     case GRX_BIGGEST_NONINTERLACED_GRAPHICS:
381       GrSetMode( GR_biggest_noninterlaced_graphics);
382       break;
383     case GRX_BIGGEST_GRAPHICS:
384       GrSetMode( GR_biggest_graphics);
385       break;
386     case GRX_BGI_EMULATION:
387 #ifdef GRX_VERSION
388       if (__gr_BGI_p > 1) {
389 	__gr_BGI_p = 2;
390 	GrSetMode( GR_custom_graphics , __gr_BGI_w, __gr_BGI_h,
391 		   COLOR_NR2DRV(__gr_BGI_c), __gr_BGI_w, 2*__gr_BGI_h);
392 	if (GrVirtualY() < 2*GrScreenY()) __gr_BGI_p = 1;
393       } else
394 #endif
395 	GrSetMode( GR_width_height_color_graphics, __gr_BGI_w,
396 		   __gr_BGI_h, COLOR_NR2DRV(__gr_BGI_c));
397       break;
398     default:
399       if (mode < __FIRST_DRIVER_SPECIFIC_MODE || mode > MM) {
400 	ERR = grInvalidMode;
401 	return;
402       }
403       if (!__gr_getmode_whc(mode, &w, &h, &c)) {
404 	ERR = grInvalidMode;
405 	return;
406       }
407 #ifdef GRX_VERSION
408 Default:
409       if (__gr_BGI_p > 1) {
410 	__gr_BGI_p = 2;
411 	GrSetMode( GR_custom_graphics , w, h, COLOR_NR2DRV(c), w, 2*h);
412 	if (GrVirtualY() < 2*GrScreenY()) __gr_BGI_p = 1;
413       } else
414 #endif
415 	GrSetMode( GR_width_height_color_graphics, w, h, COLOR_NR2DRV(c));
416       break;
417   }
418   __gr_Mode = mode;
419   graphdefaults();
420   GrClearScreen(BLACK);
421 }
422 
423 /* ----------------------------------------------------------------- */
__gr_initgraph(int * graphdriver,int * graphmode)424 void __gr_initgraph(int *graphdriver, int *graphmode) {
425   ERR = grOk;
426   if (__gr_initgraph_hook) {
427     (*__gr_initgraph_hook) ();
428     if (ERR != grOk) {
429       __gr_INIT = FALSE;
430       return;
431     }
432   } else if (!__gr_INIT) {
433     __gr_set_up_modes();
434     if (ERR != grOk) return;
435     if ( *graphdriver != NATIVE_GRX || *graphmode < 0 || *graphmode > MM)
436       *graphmode = 0;
437     __gr_INIT = TRUE;
438     setgraphmode(*graphmode);
439     if (ERR != grOk) {
440       __gr_INIT = FALSE;
441       return;
442     }
443   }
444   if (*graphmode == 0) *graphdriver = __gr_adaptcnv(__gr_ADAPTER);
445 		  else *graphdriver = NATIVE_GRX;
446 }
447 
448 
449 
closegraph(void)450 void closegraph(void)
451 {
452   if (__gr_closegraph_hook) {
453     (*__gr_closegraph_hook) ();
454     __gr_initgraph_hook = NULL;
455     __gr_closegraph_hook = NULL;
456   } else
457   restorecrtmode();
458   __gr_INIT = FALSE;
459 }
460 
461 
462 
__gr_set_libbcc_init_hooks(int (* init)(void),int (* close)(void))463 void  __gr_set_libbcc_init_hooks (
464                       int (*init) (void) ,
465                       int (*close) (void) )
466 {
467    __gr_initgraph_hook  = init;
468    __gr_closegraph_hook = close;
469 }
470 
471 
472 
initgraph(int * graphdriver,int * graphmode,char * pathtodriver)473 void initgraph(int *graphdriver, int *graphmode, char *pathtodriver) {
474   __gr_initgraph(graphdriver, graphmode);
475   strcpy(__gr_BGICHR, NULL_IS_EMPTY(pathtodriver));
476 }
477