/*
 * $Id: pc.trm,v 3.26 92/03/24 22:35:39 woo Exp Locker: woo $
 */

/* GNUPLOT - pc.trm */
/*
 * Copyright (C) 1990, 1991, 1992
 *
 * Permission to use, copy, and distribute this software and its
 * documentation for any purpose with or without fee is hereby granted, 
 * provided that the above copyright notice appear in all copies and 
 * that both that copyright notice and this permission notice appear 
 * in supporting documentation.
 *
 * Permission to modify the software is granted, but not the right to
 * distribute the modified code.  Modifications are to be distributed 
 * as patches to released version.
 *
 * This software  is provided "as is" without express or implied warranty.
 *
 * This file is included by ../term.c.
 *
 * This terminal driver supports:
 *  Under Microsoft C
 *      cga, egabios, egalib, vgabios, hercules, corona325, att
 *  Under Turboc C
 *      egalib, vgalib, vgamono, svga, mcga, cga, hercules, att
 *
 * AUTHORS
 *  Colin Kelley, Thomas Williams, William Wilson, Russell Lang
 *
 * send your comments or suggestions to (info-gnuplot@ames.arc.nasa.gov).
 *
 */

#ifdef __TURBOC__
#include <graphics.h>
#include <conio.h>
#include <dos.h>
  int g_driver, g_mode, g_error;
  char far *path;
  char *pathp, path_s[128];

/* instead of string.h */
extern char *strrchr();

get_path()
{
   path=(char far *) getenv("BGI");
   if (path==NULL) {
      (void) strcpy(path_s,_argv[0]);
      pathp=strrchr(path_s,'\\');
      *pathp=0x00;
      path=path_s;
   }
}

static struct text_info tinfo;       /* So we can restore starting text mode. */
#endif


static char near buf[80];	/* kludge since EGA.LIB is compiled SMALL */

static int pattern[] = {0xffff, 0x0f0f, 0xffff, 0xaaaa, 0x3333, 0x3f3f, 0x0f0f};

static int graphics_on = FALSE;
int startx, starty;

int pc_angle;
#define PC_VCHAR FNT5X9_VCHAR
#define PC_HCHAR FNT5X9_HCHAR

pause()		/* press any key to continue... */
{
	(void) getch();
}


PC_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
#ifdef __TURBOC__
	restorecrtmode();
        textmode(tinfo.currmode);
	clrscr();
#else
	Vmode(3);
#endif
}

PC_reset()
{
#ifdef __TURBOC__
	closegraph();
        textmode(tinfo.currmode);
	clrscr();
#endif
}


#ifndef __TURBOC__

PC_putc(x,y,c,angle,line_func)
unsigned int x,y;
char c;
int angle;
FUNC_PTR line_func;
{
int i,j,k;
unsigned int pixelon;
	i = (int)(c) - 32;
	for (j=0; j<FNT5X9_VBITS; j++) {
		for (k=0; k<FNT5X9_HBITS; k++) {
			pixelon = (((unsigned int)(fnt5x9[i][j])) >> k & 1);
			if (pixelon) {
				switch(angle) {
					case 0 : (*line_func)(x+k+1,y-j,x+k+1,y-j);
							break;
					case 1 : (*line_func)(x-j,y-k-1,x-j,y-k-1);
							break;
				}
			}
		}
	}
}


int PC_text_angle(ang)
int ang;
{
	pc_angle=ang;
	return TRUE;
}


#define CGA_XMAX 640
#define CGA_YMAX 200

#define CGA_XLAST (CGA_XMAX - 1)
#define CGA_YLAST (CGA_YMAX - 1)

#define CGA_VCHAR PC_VCHAR
#define CGA_HCHAR PC_HCHAR
#define CGA_VTIC 4
#define CGA_HTIC 6

int line_cga;

CGA_init()
{
	PC_color(1);		/* monochrome */
}

CGA_graphics()
{
	graphics_on = TRUE;
	Vmode(6);
}

#define CGA_text PC_text

CGA_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	line_cga=linetype;
	PC_mask(pattern[linetype+2]);
}

CGA_move(x,y)
{
	startx = x;
	starty = y;
}


CGA_vector(x,y)
{
	PC_line(startx,CGA_YLAST-starty,x,CGA_YLAST-y);
	startx = x;
	starty = y;
}


CGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
int i;
int line;
	line= line_cga; 	/* disable the dotted lines temporarily */
	PC_mask(pattern[0]);
	switch(pc_angle) {
		case 0 : y -= CGA_VCHAR/2;
				break;
		case 1 : x += CGA_VCHAR/2;
				break;
	}
	for (i=0;str[i];i++) {
		PC_putc(x,CGA_YLAST-y,str[i],pc_angle,PC_line);
		switch(pc_angle) {
			case 0 : x+=CGA_HCHAR ;
					break;
			case 1 : y+=CGA_HCHAR ;
					break;
		}
	}
	PC_mask(pattern[line]);  /* enable dotted lines */
}


#define CGA_text_angle PC_text_angle

#define CGA_reset PC_reset


#define EGA_XMAX 640
#define EGA_YMAX 350

#define EGA_XLAST (EGA_XMAX - 1)
#define EGA_YLAST (EGA_YMAX - 1)

#define EGA_VCHAR PC_VCHAR
#define EGA_HCHAR PC_HCHAR
#define EGA_VTIC 4
#define EGA_HTIC 5

static int ega64color[] =  {1,1,5,4,3,5,4,3, 5, 4, 3, 5, 4, 3,5};
static int ega256color[] = {7,8,2,3,4,5,9,14,12,15,13,10,11,1,6};

static int *egacolor;


EGA_init()
{
	PC_mask(0xffff);
	egacolor = ega256color;		/* should be smarter */
}

EGA_graphics()
{
	graphics_on = TRUE;
	Vmode(16);
}

#define EGA_text PC_text

EGA_linetype(linetype)
{
	if (linetype >= 13)
		linetype %= 13;
	PC_color(egacolor[linetype+2]);
}

EGA_move(x,y)
{
	startx = x;
	starty = y;
}

EGA_vector(x,y)
{
	PC_line(startx,EGA_YLAST-starty,x,EGA_YLAST-y);
	startx = x;
	starty = y;
}


EGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
int i;
	switch(pc_angle) {
		case 0 : y -= EGA_VCHAR/2;
				break;
		case 1 : x += EGA_VCHAR/2;
				break;
	}
	for (i=0;str[i];i++) {
		PC_putc(x,EGA_YLAST-y,str[i],pc_angle,PC_line);
		switch(pc_angle) {
			case 0 : x+=EGA_HCHAR ;
					break;
			case 1 : y+=EGA_HCHAR ;
					break;
		}
	}
}


#define EGA_text_angle PC_text_angle

#define EGA_reset PC_reset



/* The following VGA routines are hacked from the above EGA routines
   They worked on two VGA cards.
   Russell Lang, eln272v@monu1.cc.monash.oz */
#define VGA_XMAX 640
#define VGA_YMAX 480

#define VGA_XLAST (VGA_XMAX - 1)
#define VGA_YLAST (VGA_YMAX - 1)

#define VGA_VCHAR PC_VCHAR
#define VGA_HCHAR PC_HCHAR
#define VGA_VTIC 5
#define VGA_HTIC 5

static int vga256color[] = {7,8,2,3,4,5,9,14,12,15,13,10,11,1,6};

static int *vgacolor;


VGA_init()
{
	PC_mask(0xffff);
	vgacolor = vga256color;		/* should be smarter */
}

VGA_graphics()
{
	graphics_on = TRUE;
	Vmode(18);
}

#define VGA_text PC_text

VGA_linetype(linetype)
{
	if (linetype >= 13)
		linetype %= 13;
	PC_color(vgacolor[linetype+2]);
}

VGA_move(x,y)
{
	startx = x;
	starty = y;
}

VGA_vector(x,y)
{
	PC_line(startx,VGA_YLAST-starty,x,VGA_YLAST-y);
	startx = x;
	starty = y;
}


VGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
int i;
	switch(pc_angle) {
		case 0 : y -= VGA_VCHAR/2;
				break;
		case 1 : x += VGA_VCHAR/2;
				break;
	}
	for (i=0;str[i];i++) {
		PC_putc(x,VGA_YLAST-y,str[i],pc_angle,PC_line);
		switch(pc_angle) {
			case 0 : x+=VGA_HCHAR ;
					break;
			case 1 : y+=VGA_HCHAR ;
					break;
		}
	}
}


#define VGA_text_angle PC_text_angle

#define VGA_reset PC_reset



#ifdef EGALIB

#define EGALIB_XMAX 640
#define EGALIB_YMAX 350

#define EGALIB_XLAST (EGA_XMAX - 1)
#define EGALIB_YLAST (EGA_YMAX - 1)

#define EGALIB_VCHAR 14
#define EGALIB_HCHAR 8
#define EGALIB_VTIC 4
#define EGALIB_HTIC 5

#include "mcega.h"

EGALIB_init()
{
	GPPARMS();
	if (GDTYPE != 5) {
		term = 0;
		int_error("color EGA board not found",NO_CARET);
	}
	egacolor = (GDMEMORY < 256) ? ega64color : ega256color;
}

EGALIB_graphics()
{
	graphics_on = TRUE;
	GPINIT();
}

EGALIB_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
	GPTERM();
}

EGALIB_linetype(linetype)
{
	if (linetype >= 13)
		linetype %= 13;
	GPCOLOR(egacolor[linetype+2]);
}

EGALIB_move(x,y)
{
	GPMOVE(x,GDMAXROW-y);
}


EGALIB_vector(x,y)
{
	GPLINE(x,GDMAXROW-y);
}


EGALIB_put_text(x,y,str)
int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	GotoXY((int)(x/EGALIB_HCHAR),
		   (int)((EGALIB_YMAX-y-(EGALIB_VCHAR/2))/EGALIB_VCHAR));
	gprintf(buf);
}


#define EGALIB_reset PC_reset

#endif /* EGALIB */


#ifdef HERCULES

#define HERC_XMAX 720
#define HERC_YMAX 348

#define HERC_XLAST (HERC_XMAX - 1)
#define HERC_YLAST (HERC_YMAX - 1)

#define HERC_VCHAR PC_VCHAR
#define HERC_HCHAR PC_HCHAR
#define HERC_VTIC 4
#define HERC_HTIC 5

int line_herc;

HERC_init()
{
	H_init();
}

HERC_graphics()
{
	HVmode(1);
	graphics_on = TRUE;
}

HERC_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
	HVmode(0);
}

HERC_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	H_mask(pattern[linetype+2]);
	line_herc = linetype;
}

HERC_move(x,y)
{
	if (x < 0)
		startx = 0;
	else if (x > HERC_XLAST)
		startx = HERC_XLAST;
	else
		startx = x;

	if (y < 0)
		starty = 0;
	else if (y > HERC_YLAST)
		starty = HERC_YLAST;
	else
		starty = y;
}

HERC_vector(x,y)
{
	if (x < 0)
		x = 0;
	else if (x > HERC_XLAST)
		x = HERC_XLAST;
	if (y < 0)
		y = 0;
	else if (y > HERC_YLAST)
		y = HERC_YLAST;

	H_line(startx,HERC_YLAST-starty,x,HERC_YLAST-y);
	startx = x;
	starty = y;
}


HERC_put_text(x,y,str)
unsigned int x, y;
char *str;
{
int i;
int line;
	line= line_herc; 	/* disable the dotted lines temporarily */
	H_mask(pattern[0]);
	switch(pc_angle) {
		case 0 : y -= HERC_VCHAR/2;
				break;
		case 1 : x += HERC_VCHAR/2;
				break;
	}
	for (i=0;str[i];i++) {
		PC_putc(x,HERC_YLAST-y,str[i],pc_angle,H_line);
		switch(pc_angle) {
			case 0 : x+=HERC_HCHAR ;
					break;
			case 1 : y+=HERC_HCHAR ;
					break;
		}
	}
	H_mask(pattern[line]);  /* enable dotted lines */
}


#define HERC_text_angle PC_text_angle

#define HERC_reset PC_reset


#endif /* HERCULES */


/* thanks to sask!macphed (Geoff Coleman and Ian Macphedran) for the
   ATT 6300 driver */ 


#ifdef ATT6300

#define ATT_XMAX 640
#define ATT_YMAX 400

#define ATT_XLAST (ATT_XMAX - 1)
#define ATT_YLAST (ATT_YMAX - 1)

#define ATT_VCHAR PC_VCHAR
#define ATT_HCHAR PC_HCHAR
#define ATT_VTIC 4
#define ATT_HTIC 5

#define ATT_init CGA_init

ATT_graphics()
{
	graphics_on = TRUE;
	Vmode(0x40);        /* 40H is the magic number for the AT&T driver */
}

#define ATT_text CGA_text

#define ATT_linetype CGA_linetype

#define ATT_move CGA_move

ATT_vector(x,y)
{
	PC_line(startx,ATT_YLAST-starty,x,ATT_YLAST-y);
	startx = x;
	starty = y;
}


ATT_put_text(x,y,str)
unsigned int x, y;
char *str;
{
int i;
int line;
	line= line_cga; 	/* disable the dotted lines temporarily */
	PC_mask(pattern[0]);
	switch(pc_angle) {
		case 0 : y -= ATT_VCHAR/2;
				break;
		case 1 : x += ATT_VCHAR/2;
				break;
	}
	for (i=0;str[i];i++) {
		PC_putc(x,ATT_YLAST-y,str[i],pc_angle,PC_line);
		switch(pc_angle) {
			case 0 : x+=ATT_HCHAR ;
					break;
			case 1 : y+=ATT_HCHAR ;
					break;
		}
	}
	PC_mask(pattern[line]);  /* enable dotted lines */
}


#define ATT_text_angle PC_text_angle

#define ATT_reset CGA_reset

#endif  /* ATT6300 */


#ifdef CORONA

#define COR_XMAX 640
#define COR_YMAX 325

#define COR_XLAST (COR_XMAX - 1)
#define COR_YLAST (COR_YMAX - 1)

#define COR_VCHAR PC_VCHAR
#define COR_HCHAR PC_HCHAR
#define COR_VTIC 4
#define COR_HTIC 5

int line_cor;

static int corscreen;		/* screen number, 0 - 7 */

COR_init()
{
register char *p;
	if (!(p = getenv("CORSCREEN")))
		int_error("must run CORPLOT for Corona graphics",NO_CARET);
	corscreen = *p - '0';
}

COR_graphics()
{
	graphics_on = TRUE;
	Vmode(3);				/* clear text screen */
	grinit(corscreen);
	grandtx();
}

COR_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
	grreset();
	txonly();
	Vmode(3);
}

COR_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	line_cor = linetype;
	Cor_mask(pattern[linetype+2]);
}

COR_move(x,y)
{
	if (x < 0)
		startx = 0;
	else if (x > COR_XLAST)
		startx = COR_XLAST;
	else
		startx = x;

	if (y < 0)
		starty = 0;
	else if (y > COR_YLAST)
		starty = COR_YLAST;
	else
		starty = y;
}

COR_vector(x,y)
{
	if (x < 0)
		x = 0;
	else if (x > COR_XLAST)
		x = COR_XLAST;
	if (y < 0)
		y = 0;
	else if (y > COR_YLAST)
		y = COR_YLAST;

	Cor_line(startx,COR_YLAST-starty,x,COR_YLAST-y);
	startx = x;
	starty = y;
}


COR_put_text(x,y,str)
unsigned int x, y;
char *str;
{
int i;
int line;
	line= line_cor; 	/* disable the dotted lines temporarily */
	Cor_mask(pattern[0]);
	switch(pc_angle) {
		case 0 : y -= COR_VCHAR/2;
				break;
		case 1 : x += COR_VCHAR/2;
				break;
	}
	for (i=0;str[i];i++) {
		PC_putc(x,COR_YLAST-y,str[i],pc_angle,Cor_line);
		switch(pc_angle) {
			case 0 : x+=COR_HCHAR ;
					break;
			case 1 : y+=COR_HCHAR ;
					break;
		}
	}
	COR_mask(pattern[line]);  /* enable dotted lines */
}


#define COR_text_angle PC_text_angle

#define COR_reset PC_reset

#endif /* CORONA */


#else /* ifndef __TURBOC__ */
/* all of the Turbo C routines for the different graphics devices go here */

#define VGA_XMAX 640
#define VGA_YMAX 480

#define VGA_XLAST (VGA_XMAX - 1)
#define VGA_YLAST (VGA_YMAX - 1)

#define VGA_VCHAR 10
#define VGA_HCHAR 8
#define VGA_VTIC 4
#define VGA_HTIC 5

#define SVGA_XMAX 640
#define SVGA_YMAX 480

#define SVGA_VCHAR 10
#define SVGA_HCHAR 8
#define SVGA_VTIC 4
#define SVGA_HTIC 5

static int vga256color[] = {7,8,2,3,4,5,9,14,12,15,13,10,11,1,6};
static int *vgacolor;

static int svga_xmax = SVGA_XMAX,
	   svga_ymax = SVGA_YMAX,
	   svga_xlast = 639,
	   svga_ylast = 479;

#define VGA_reset EGALIB_reset
#define VGA_text EGALIB_text
#define VGA_move EGALIB_move
#define VGA_vector EGALIB_vector
#define VGA_text_angle PC_text_angle
#define VGA_justify_text PC_justify_text

#define SVGA_reset EGALIB_reset
#define SVGA_text EGALIB_text
#define SVGA_move EGALIB_move
#define SVGA_vector EGALIB_vector
#define SVGA_text_angle PC_text_angle
#define SVGA_justify_text PC_justify_text
#define SVGA_linetype VGA_linetype

int PC_text_angle(ang)
int ang;
{
	int size = svga_ymax > 600 ? 2 : 1;

	pc_angle = ang;

	switch (ang) {
		case 0 : settextstyle(DEFAULT_FONT,HORIZ_DIR,size);
			break;
		case 1 : settextstyle(DEFAULT_FONT,VERT_DIR,size);
			break;
	}
	return TRUE;
}

int PC_justify_text(mode)
enum JUSTIFY mode;
{
	switch(mode) {
		case LEFT :
			settextjustify(LEFT_TEXT,CENTER_TEXT);
			break;
		case CENTRE :
			settextjustify(CENTER_TEXT,CENTER_TEXT);
			break;
		case RIGHT:
			settextjustify(RIGHT_TEXT,CENTER_TEXT);
			break;
	}
	return TRUE;
}

VGA_init()
{
	g_driver=VGA;
	g_mode=2;
	gettextinfo(&tinfo);
        initgraph(&g_driver,&g_mode,path);
        if(g_driver!=9){
          term=0;
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }

/*          int_error("color VGA board not found",NO_CARET);*/
        }
        if(g_driver==VGA) vgacolor=vga256color;
}

VGA_graphics()
{       g_driver=VGA;
	g_mode=2;
	graphics_on = TRUE;
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	VGA_justify_text(LEFT);
}

VGA_linetype(linetype)
{
	if (linetype >= 13)
		linetype %= 13;
	setcolor(vgacolor[linetype+2]);
}

VGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,VGA_YLAST-y,buf);
}


VGAMONO_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	setlinestyle(4,pattern[linetype+2],1);
}

static int huge detect_svga(void)
{
    return g_mode;
}

SVGA_init()
{
	char *p, name[128], *SVGA = getenv( "SVGA" );

	if (SVGA == NULL)
		int_error("'SVGA' driver environment variable is not set",
			  NO_CARET);

	strcpy(name, SVGA);
	if ((p = strrchr(name, '.')) == NULL ||
	    sscanf(&p[1], "%d", &g_mode) != 1)
		int_error("'SVGA' envvar should be of the form 'name.mode'",
			  NO_CARET);

	*p = 0;

	installuserdriver(name, detect_svga);
	gettextinfo(&tinfo);
	g_driver = 0;
        initgraph(&g_driver,&g_mode,path);
        if(g_driver<0){
          term=0;
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }

        }
	else
	    vgacolor=vga256color;

	/* Get the screen size: */
	svga_xmax = term_tbl[term].xmax = getmaxx() + 1;
        svga_ymax = term_tbl[term].ymax = getmaxy() + 1;
	svga_xlast = svga_xmax-1;
	svga_ylast = svga_ymax-1;

	if (svga_ymax > 600) {		       /* Double the tic/font sizes. */
		term_tbl[term].h_char = SVGA_HCHAR * 2;
		term_tbl[term].v_char = SVGA_VCHAR * 2;
		term_tbl[term].h_tic = SVGA_HTIC * 2;
		term_tbl[term].v_tic = SVGA_VTIC * 2;
		settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
 	}
	else
		settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
}

SVGA_graphics()
{
	graphics_on = TRUE;
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	VGA_justify_text(LEFT);

        svga_ymax = getmaxy() + 1;
	if (svga_ymax > 600)		       /* Double the tic/font sizes. */
		settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
	else
		settextstyle(DEFAULT_FONT,HORIZ_DIR,1);
}

SVGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,svga_ylast-y,buf);
}

#define MCGA_XMAX 640
#define MCGA_YMAX 480

#define MCGA_XLAST (MCGA_XMAX - 1)
#define MCGA_YLAST (MCGA_YMAX - 1)

#define MCGA_VCHAR 10
#define MCGA_HCHAR 8
#define MCGA_VTIC 4
#define MCGA_HTIC 5

static int *MCGAcolor;

#define MCGA_reset EGALIB_reset
#define MCGA_text EGALIB_text
#define MCGA_move EGALIB_move
#define MCGA_vector EGALIB_vector
#define MCGA_text_angle PC_text_angle
#define MCGA_justify_text PC_justify_text

MCGA_init()
{
	g_driver=MCGA;
	g_mode=5;
	gettextinfo(&tinfo);
        initgraph(&g_driver,&g_mode,path);
        if(g_driver!=2){
          term=0;
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }
        }
}

MCGA_graphics()
{
	graphics_on = TRUE;
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	MCGA_justify_text(LEFT);
}


MCGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,MCGA_YLAST-y,buf);
}


MCGA_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	setlinestyle(4,pattern[linetype+2],1);
}


#define EGALIB_XMAX 640
#define EGALIB_YMAX 350

#define EGALIB_XLAST (EGALIB_XMAX - 1)
#define EGALIB_YLAST (EGALIB_YMAX - 1)

#define EGALIB_VCHAR 10
#define EGALIB_HCHAR 8
#define EGALIB_VTIC 4
#define EGALIB_HTIC 5

static int ega64color[] =  {1,1,5,4,3,5,4,3, 5, 4, 3, 5, 4, 3,5};
static int ega256color[] = {7,8,2,3,4,5,9,14,12,15,13,10,11,1,6};

static int *egacolor;

#define EGALIB_text_angle PC_text_angle
#define EGALIB_justify_text PC_justify_text

EGALIB_init()
{
	g_driver=EGA;
	g_mode=1;
	gettextinfo(&tinfo);
        initgraph(&g_driver,&g_mode,path);
        if(g_driver<3 || g_driver>4){
          term=0;
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }

/*          int_error("color EGA board not found",NO_CARET);*/
        }
        if(g_driver==EGA) egacolor=ega256color;
        if(g_driver==EGA64) egacolor=ega64color;
}

EGALIB_graphics()
{
	graphics_on = TRUE;
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	EGALIB_justify_text(LEFT);
}

EGALIB_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
	restorecrtmode();
        textmode(tinfo.currmode);
	clrscr();
	svga_ymax = SVGA_YMAX; /* Since it may double font size if too high. */
}

EGALIB_linetype(linetype)
{
	if (linetype >= 13)
		linetype %= 13;
	setcolor(egacolor[linetype+2]);
}

EGALIB_move(x,y)
{
        moveto(x,getmaxy()-y);
}


EGALIB_vector(x,y)
{
	lineto(x,getmaxy()-y);
}


EGALIB_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,EGALIB_YLAST-y,buf);
}


EGALIB_reset()
{
  	closegraph();
        textmode(tinfo.currmode);
	clrscr();
	svga_ymax = SVGA_YMAX; /* Since it may double font size if too high. */
}


#define CGA_XMAX 640
#define CGA_YMAX 200

#define CGA_XLAST (CGA_XMAX - 1)
#define CGA_YLAST (CGA_YMAX - 1)

#define CGA_VCHAR 10
#define CGA_HCHAR 8
#define CGA_VTIC 4
#define CGA_HTIC 6

#define CGA_text_angle PC_text_angle
#define CGA_justify_text PC_justify_text
#define CGA_reset PC_reset

CGA_init()
{
	g_driver=CGA;
	g_mode=4;
	gettextinfo(&tinfo);
	initgraph(&g_driver,&g_mode,path);
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }
/*	PC_color(1);		 monochrome */

}

CGA_graphics()
{
	graphics_on = TRUE;
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	CGA_justify_text(LEFT);
	/*	Vmode(6);*/
}

#define CGA_text PC_text

CGA_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	setlinestyle(4,pattern[linetype+2],1);
}

CGA_move(x,y)
{
	moveto(x,getmaxy()-y);
}


CGA_vector(x,y)
{
	lineto(x,getmaxy()-y);
}

CGA_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,CGA_YLAST-y,buf);
}



#define HERC_XMAX 720
#define HERC_YMAX 348

#define HERC_XLAST (HERC_XMAX - 1)
#define HERC_YLAST (HERC_YMAX - 1)

#define HERC_VCHAR 10
#define HERC_HCHAR 8
#define HERC_VTIC 4
#define HERC_HTIC 5

#define HERC_text_angle PC_text_angle
#define HERC_justify_text PC_justify_text
#define HERC_reset PC_reset

HERC_init()
{
	g_driver=HERCMONO;
	g_mode=0;
	gettextinfo(&tinfo);
  	initgraph(&g_driver,&g_mode,path);
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }
}

HERC_graphics()
{
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	HERC_justify_text(LEFT);
	graphics_on = TRUE;
}

HERC_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
	restorecrtmode();
        textmode(tinfo.currmode);
	clrscr();
}

HERC_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	setlinestyle(4,pattern[linetype+2],1);
}

HERC_move(x,y)
{
	if (x < 0)
		x = 0;
	else if (x > HERC_XLAST)
		x = HERC_XLAST;

	if (y < 0)
		y = 0;
	else if (y > HERC_YLAST)
		y = HERC_YLAST;
	moveto(x,getmaxy()-y);
}

HERC_vector(x,y)
{
	if (x < 0)
		x = 0;
	else if (x > HERC_XLAST)
		x = HERC_XLAST;
	if (y < 0)
		y = 0;
	else if (y > HERC_YLAST)
		y = HERC_YLAST;

	lineto(x,getmaxy()-y);
}


HERC_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,HERC_YLAST-y,buf);
}


#ifdef ATT6300
/* this driver added by rjl@monu1.cc.monash.edu.au */

#define ATT_XMAX 640
#define ATT_YMAX 400

#define ATT_XLAST (ATT_XMAX - 1)
#define ATT_YLAST (ATT_YMAX - 1)

#define ATT_VCHAR PC_VCHAR
#define ATT_HCHAR PC_HCHAR
#define ATT_VTIC 4
#define ATT_HTIC 5

#define ATT_text_angle PC_text_angle
#define ATT_justify_text PC_justify_text
#define ATT_reset PC_reset

ATT_init()
{
	g_driver=ATT400;
	g_mode=5;
	gettextinfo(&tinfo);
  	initgraph(&g_driver,&g_mode,path);
          switch (g_driver){
            case -2: fprintf(stderr,"Graphics card not detected.\n");
                     break;
            case -3: fprintf(stderr,"BGI driver file cannot be found.\n");
                     break;
            case -4: fprintf(stderr,"Invalid BGI driver file.\n");
                     break;
            case -5: fprintf(stderr,"Insufficient memory to load ",
                             "graphics driver.");
                     break;
            }
}

ATT_graphics()
{
	gettextinfo(&tinfo);
	setgraphmode(getgraphmode());
	ATT_justify_text(LEFT);
	graphics_on = TRUE;
}

ATT_text()
{
	if (graphics_on) {
		graphics_on = FALSE;
		pause();
	}
	restorecrtmode();
        textmode(tinfo.currmode);
	clrscr();
}

ATT_linetype(linetype)
{
	if (linetype >= 5)
		linetype %= 5;
	setlinestyle(4,pattern[linetype+2],1);
}

ATT_move(x,y)
{
	if (x < 0)
		x = 0;
	else if (x > ATT_XLAST)
		x = ATT_XLAST;

	if (y < 0)
		y = 0;
	else if (y > ATT_YLAST)
		y = ATT_YLAST;
	moveto(x,getmaxy()-y);
}

ATT_vector(x,y)
{
	if (x < 0)
		x = 0;
	else if (x > ATT_XLAST)
		x = ATT_XLAST;
	if (y < 0)
		y = 0;
	else if (y > ATT_YLAST)
		y = ATT_YLAST;

	lineto(x,getmaxy()-y);
}


ATT_put_text(x,y,str)
unsigned int x, y;
char *str;
{
	strcpy((char far *)buf,str);
	outtextxy(x,ATT_YLAST-y,buf);
}
#endif /* ifdef ATT6300 */

#endif /* ifndef __TURBOC__ */

