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