/*
* $Id: amiga.trm,v 3.26 92/03/24 22:34:45 woo Exp Locker: woo $
*/
/* GNUPLOT - amiga.trm */
/*
* Copyright (C) 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:
* Amiga Custom Screen
*
* AUTHORS
* Carsten Steger
*
* Pat R. Empleo Slightly modified for Aztec C v5.2a (beta); sort of
* 08/27/91 supports overscan; for large WB 2.0 virtual screens,
* we limit the plot size so we don't have to scroll
* around (not fun).
*
* Carsten Steger Modified to support Kickstart 2.0.
* 09/11/91 Opens a text overscan screen when used with WB 2.0.
* Discerns between NTSC and PAL Amigas when used with
* WB 1.3 and lower.
*
* Pat R. Empleo Defined some 2.0 stuff in order to get Aztec C to
* 09/20/91 work with Carsten's new code (see above). When
* KS/WB 2.0 support gets implemented in Aztec C, this
* kludge will get deleted!
* (Aztec C release 5.2 beta)
*
* send your comments or suggestions to (info-gnuplot@ames.arc.nasa.gov).
*
*/
#ifdef AMIGA_AC_5
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#else
/* You will have to use the Kickstart 2.0 header files for this to compile */
#include <exec/types.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/exec.h>
#include <proto/diskfont.h>
#endif
extern char *getenv(),*strchr();
#define AMIGA_XMAX 640
#define AMIGA_YMAX 512
#define AMIGA_VCHAR (12)
#define AMIGA_HCHAR (8)
#define AMIGA_VTIC (AMIGA_YMAX/80)
#define AMIGA_HTIC (AMIGA_XMAX/80)
/* The origin is in the upper left hand corner, so we have to translate */
/* and flip the coordinates: */
#define AMIGA_VTF(y) (AMIGA_ymax-1-(y))
struct IntuitionBase *IntuitionBase;
struct GfxBase *GfxBase;
struct Library *DiskfontBase;
static struct TextAttr AMIGA_Font = {
"topaz.font",TOPAZ_EIGHTY,FS_NORMAL,FPF_ROMFONT
};
static struct TextFont *AMIGA_TextFont;
static struct NewScreen AMIGA_NewScreen = {
0,0,AMIGA_XMAX,AMIGA_YMAX,4,15,0,HIRES|LACE,
CUSTOMSCREEN|SCREENBEHIND|SCREENQUIET,NULL,NULL,NULL,NULL
};
static struct Screen *AMIGA_Screen;
static UWORD AMIGA_Colors [] = {
0x000,0xfff,0xbbb,0x0f0,0xf00,0x00f,0x3ca,0xf0f,
0x94d,0x0ff,0x82f,0xff0,0x0af,0xc5e,0xfa2,0xf44
};
static int AMIGA_slinetype;
static enum JUSTIFY AMIGA_justify = LEFT;
static unsigned int AMIGA_ymax,AMIGA_xmax;
static WORD AMIGA_cwd,AMIGA_cht,AMIGA_bsl,AMIGA_vadj;
static struct TagItem AMIGA_ScrTagList[] = {
{SA_Overscan,OSCAN_TEXT},{TAG_DONE,0}
};
AMIGA_reset()
{
if (AMIGA_TextFont != NULL) CloseFont(AMIGA_TextFont);
if (DiskfontBase != NULL) CloseLibrary(DiskfontBase);
if (AMIGA_Screen != NULL) CloseScreen(AMIGA_Screen);
if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
if (GfxBase != NULL) CloseLibrary(GfxBase);
AMIGA_TextFont = NULL;
DiskfontBase = NULL;
AMIGA_Screen = NULL;
IntuitionBase = NULL;
GfxBase = NULL;
}
AMIGA_init()
{
static char fontname[80],*gnufont,*search;
static int fsize;
static char *test_str =
" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~";
static WORD test_len,test_pxl;
#ifdef AMIGA_LC_5_1
/* Install exit trap in case of abnormal termination (see below). */
int AMIGA_exit();
if (!onexit(&AMIGA_exit)) {
fprintf(stderr,"Couldn't set exit trap\n");
exit(20);
}
#endif
GfxBase = OpenLibrary("graphics.library",0);
if (GfxBase == NULL) {
fprintf(stderr,"No Graphics-Library\n");
AMIGA_reset();
exit(20);
}
IntuitionBase = OpenLibrary("intuition.library",0);
if (IntuitionBase == NULL) {
fprintf(stderr,"No Intuition-Library\n");
AMIGA_reset();
exit(20);
}
if (IntuitionBase->LibNode.lib_Version <= 34) {
/* We compute the vertical resolution for those poor NTSC-souls :-) */
if (GfxBase->DisplayFlags & PAL) AMIGA_ymax = 512;
else AMIGA_ymax = 400;
AMIGA_xmax = 640;
AMIGA_NewScreen.Width = AMIGA_xmax;
AMIGA_NewScreen.Height = AMIGA_ymax;
AMIGA_Screen = OpenScreen(&AMIGA_NewScreen);
if (AMIGA_Screen == NULL) {
fprintf(stderr,"No Screen\n");
AMIGA_reset();
exit(20);
}
} else {
/* Kickstart 2.0 support */
AMIGA_NewScreen.Width = STDSCREENWIDTH;
AMIGA_NewScreen.Height = STDSCREENHEIGHT;
AMIGA_Screen = OpenScreenTagList(&AMIGA_NewScreen,AMIGA_ScrTagList);
if (AMIGA_Screen == NULL) {
fprintf(stderr,"No Screen\n");
AMIGA_reset();
exit(20);
}
AMIGA_xmax = AMIGA_Screen->Width;
AMIGA_ymax = AMIGA_Screen->Height;
}
term_tbl[term].xmax = AMIGA_xmax;
term_tbl[term].ymax = AMIGA_ymax;
gnufont = getenv("GNUFONT");
if (gnufont != NULL ) {
search = strchr(gnufont,'/');
if (search != NULL) {
*search++ = '\0';
strncpy(fontname,gnufont,74);
strcat(fontname,".font");
sscanf(search,"%d",&fsize);
/* Avoid opening "diskfont.library" if a built-in font is desired */
if ((strcmp("topaz.font",fontname) == 0) &&
((fsize == TOPAZ_EIGHTY) || (fsize == TOPAZ_SIXTY))) {
AMIGA_Font.ta_Name = fontname;
AMIGA_Font.ta_YSize = fsize;
AMIGA_Font.ta_Style = FS_NORMAL;
AMIGA_Font.ta_Flags = FPF_ROMFONT;
AMIGA_TextFont = OpenFont(&AMIGA_Font);
if (AMIGA_TextFont != NULL)
SetFont(&AMIGA_Screen->RastPort,AMIGA_TextFont);
} else {
DiskfontBase = OpenLibrary("diskfont.library",0);
if (DiskfontBase != NULL) {
AMIGA_Font.ta_Name = fontname;
AMIGA_Font.ta_YSize = fsize;
AMIGA_Font.ta_Style = FS_NORMAL;
AMIGA_Font.ta_Flags = FPF_ROMFONT|FPF_DISKFONT;
AMIGA_TextFont = OpenDiskFont(&AMIGA_Font);
if (AMIGA_TextFont != NULL)
SetFont(&AMIGA_Screen->RastPort,AMIGA_TextFont);
}
}
}
}
/* Width of characters: This works better for proportional fonts than */
/* AMIGA_Screen->RastPort.TxWidth + AMIGA_Screen->RastPort.TxSpacing */
test_len = strlen(test_str);
test_pxl = TextLength(&AMIGA_Screen->RastPort,test_str,test_len);
AMIGA_cwd = test_pxl / test_len;
AMIGA_cht = AMIGA_Screen->RastPort.TxHeight; /* Height of characters */
AMIGA_bsl = AMIGA_Screen->RastPort.TxBaseline; /* Reference line */
/* Amount by which characters have to be shifted upwards to be */
/* vertically justified: */
AMIGA_vadj = AMIGA_bsl / 2;
term_tbl[term].v_char = AMIGA_cht + 4; /* So lines won't be too close */
term_tbl[term].h_char = AMIGA_cwd;
LoadRGB4(&AMIGA_Screen->ViewPort,AMIGA_Colors,16);
RemakeDisplay();
AMIGA_slinetype = 1;
SetAPen(&AMIGA_Screen->RastPort,AMIGA_slinetype);
SetDrMd(&AMIGA_Screen->RastPort,JAM1);
}
AMIGA_text()
{
char c;
c = getc(stdin); /* This is extremely ugly... Yuk !!!! >:-( */
ungetc(c,stdin); /* Maybe someone else will find a better solution */
ScreenToBack(AMIGA_Screen);
}
AMIGA_graphics()
{
SetRast(&AMIGA_Screen->RastPort,0);
SetAPen(&AMIGA_Screen->RastPort,AMIGA_slinetype);
ScreenToFront(AMIGA_Screen);
}
AMIGA_move(x,y)
unsigned int x,y;
{
if ((x>=AMIGA_xmax) || (y>=AMIGA_ymax)) return;
Move(&AMIGA_Screen->RastPort,x,AMIGA_VTF(y));
}
AMIGA_vector(x,y)
unsigned int x,y;
{
if ((x>=AMIGA_xmax) || (y>=AMIGA_ymax)) return;
Draw(&AMIGA_Screen->RastPort,x,AMIGA_VTF(y));
}
AMIGA_linetype(linetype)
int linetype;
{
if (linetype >= 13) linetype %= 13;
AMIGA_slinetype = linetype+3;
SetAPen(&AMIGA_Screen->RastPort,AMIGA_slinetype);
}
AMIGA_put_text(x,y,str)
unsigned int x,y;
char *str;
{
LONG len,tx_len;
WORD xmin,xmax,ymin,ymax;
len = strlen(str);
tx_len = TextLength(&AMIGA_Screen->RastPort,str,len);
switch (AMIGA_justify) {
case LEFT:
xmin = x;
xmax = x + tx_len;
break;
case CENTRE:
xmin = x - tx_len / 2;
xmax = x + tx_len - tx_len / 2; /* aviod roundoff errors ! */
break;
case RIGHT:
xmin = x - tx_len;
xmax = x;
break;
}
ymin = AMIGA_VTF(y) - AMIGA_vadj;
ymax = ymin + AMIGA_cht;
/* Check if character-string lies completely within the screen: */
if ((xmax >= AMIGA_xmax) || (ymin < 0) || (ymax >= AMIGA_ymax)) return;
Move(&AMIGA_Screen->RastPort,xmin,ymin+AMIGA_bsl);
Text(&AMIGA_Screen->RastPort,str,len);
}
int AMIGA_justify_text(mode)
enum JUSTIFY mode;
{
AMIGA_justify = mode;
return TRUE;
}
/* This function is mainly included if the program terminates abnormally */
/* and the screen and libraries are still open. It closes down all opened */
/* libraries and screens. This happens e.g. when loading "bivariat.demo" */
/* and the stack is smaller than 70000 bytes. */
#ifdef AMIGA_LC_5_1
int AMIGA_exit(rc)
int rc;
{
AMIGA_reset();
return rc;
}
#endif