home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d108
/
tek.lha
/
Tek
/
tek.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-10-31
|
20KB
|
800 lines
/* This module is a minimum extenal hooks tek 4010 emulation, the
* function InitTek() must be called before any of the others, it
* assumes that gfx, intuition are open. Tek() returns true if it
* uses the input stream else false. It must be called before any
* character parsing or you could get into trouble. CloseTek() Frees
* up all resources used by this module */
/* I had to invent a few commands for area fill reset screen, and
* color setting. Any one who knows the correct commands please let me
* know the line drawing and color index selection are standard commands.
* I have vax software to drive the 640x400 mode, and it works really well.
* the 1024x780 mode is not quite as clear, but works ok.
* The author of this software can be contacted as:
* T.Whelan
* Dept. of Physics & Astronomy
* University of Iowa
* Iowa City
* IA 52244
* and on span at IOWA::WHELAN
* on the "to do" list, are graphic input mode and run time selection
* of the screen resolution. */
/******************************************************************/
/* Now built on top of vt100 v2.6
/* Mods added by NG 4-87
/******************************************************************/
/* compiler directives to fetch the necessary header files */
#include "vt100.h"
#include <graphics/display.h>
/*********************** tek defaults *******************************/
int t_scale = 0; /* 0->1024x780 1->640x400 resolution */
int t_on = 0; /* 0 = no 1 = yes come up with tek screen on */
int t_depth = 1; /* depth of tek screen */
int t_interlace = 1; /* interlace tek screen 0=no 1=yes */
int TekMode = FALSE;
/* global pointers, used only in this code module */
struct Screen *TekScreen;
struct Window *TekWindow;
void *TekFillRas; /* was an int * in 1.1 */
int Tek_screen_open = 0; /* new variable added by NG */
extern void * AllocRaster(); /* was an int * in 1.1 */
/* macros... */
#define mrp TekWindow->RPort
#define COLOR(i, j, k, l) SetRGB4(&TekScreen->ViewPort, i, j, k, l)
/* this macro puts the tek screen at the back
* and sets things so that the user gets the
* non-tek mode of operation, there are some problems here
* as we do not use intuition to control window positions */
#define TekOFF() {TekMode = FALSE; \
ScreenToBack(TekScreen); }
#define clear() SetRast(mrp, 0L); /* set the screen to color Zero */
/* the screen size */
#define xmin 0
#define ymin 0
#define xmax 640 /* changed from old tek version */
#define ymax 400
struct NewScreen TekNewScreen = {
xmin, ymin,
xmax, ymax, 1, /* 1 bit plane is now the default */
0, 1,
HIRES|INTERLACE, /* now the default */
CUSTOMSCREEN,
NULL,
NULL,
NULL,
NULL
};
struct NewWindow TekNewWindow = {
xmin, ymin,
xmax, ymax,
1, 0,
RAWKEY, /* No IDCMP flags */
BORDERLESS|NOCAREREFRESH|SMART_REFRESH,
NULL,
NULL,
NULL,
NULL,
NULL,
0, 0,
0, 0,
CUSTOMSCREEN
};
/******** tek menu stuff *******/
struct MenuItem TekItem[TekParamsMax];
struct IntuiText TekText[TekParamsMax];
struct MenuItem TekScaleItem[TekScaleMax];
struct IntuiText TekScaleText[TekScaleMax];
struct MenuItem TekDepthItem[TekDepthMax];
struct IntuiText TekDepthText[TekDepthMax];
struct MenuItem TekInterlaceItem[TekInterlaceMax];
struct IntuiText TekInterlaceText[TekInterlaceMax];
struct MenuItem TekScreenItem[TekScreenMax];
struct IntuiText TekScreenText[TekScreenMax];
struct MenuItem TekSelectItem[TekSelectMax];
struct IntuiText TekSelectText[TekSelectMax];
/* initalize the window and screen needed for this mode
* inituition and gfx are assumed open */
/* was called InitTek in old version - now this function just opens
the tek screen so rename it */
OpenTek(HisPort)
struct MsgPort *HisPort;
{
static struct AreaInfo ai;
static WORD buffer[250];
static struct TmpRas tr;
if(doing_init == 1)
return(FALSE);
if(Tek_screen_open == 1)
return(FALSE);
TekScreen = (struct Screen *)OpenScreen(&TekNewScreen);
if (TekScreen == NULL) {
emits("Cannot open Tek screen\n");
return TRUE;
}
TekNewWindow.Screen = TekScreen;
TekWindow = (struct Window *)OpenWindow(&TekNewWindow);
if (TekWindow == NULL){
emits("Cannot open Tek window\n");
return TRUE;
}
/* make HisPort the User Port for this window, so that his
* read routines will work when my screen is active
*/
TekWindow->UserPort = HisPort;
ModifyIDCMP(TekWindow, RAWKEY|MENUPICK);
/* allow for area fill */
InitArea (&ai, buffer, 100L);
mrp->AreaInfo = &ai;
TekFillRas = AllocRaster((long)xmax, (long)ymax);
/* mrp->TmpRas = InitTmpRas(&tr, TekFillRas, RASSIZE((long)xmax, (long)ymax)); this worked with 1.1 */
InitTmpRas(&tr, TekFillRas, RASSIZE((long)xmax, (long)ymax));
reset();
TekOFF();
Tek_screen_open = 1; /* added by NG */
return FALSE; /* no errors detected */
}
InitTekDev()
{
if(t_on == 1)
OpenTek();
}
CloseTek()
{
if(Tek_screen_open == 0)
return;
TekMode = FALSE;
FreeRaster(TekFillRas,(long)xmax,(long)ymax);
TekWindow->UserPort = NULL; /* I will not close his port */
CloseWindow(TekWindow);
CloseScreen(TekScreen);
Tek_screen_open = 0;
}
/*************************************************
* Function to do tek 4010 graphics and mode
* switching, the function returns false if it
* uses the character else the
* character can be used for something else
*************************************************/
int Tek(c)
char c;
{
#define dx 8
#define dy 10
static int x = xmin, xl;
static int y = ymin + dy, yl;
static int last, escmode = FALSE, boxmode = FALSE;
static int loy, hix, hiy;
/* static enum {alpha, line, move, point} mode; */
/* manx 3.2 did not have enum data types */
#define alpha 1
#define line 2
#define move 3
#define point 4
static int mode;
static colormode = NULL, index, red, green;
#define COLORSET 1024
static int tk4100 = NULL;
static int ic = 1;
static int lastc = 1;
if (TekMode) goto top;
if (c == 29) {
TekMode = TRUE;
if(Tek_screen_open == 0)
return TRUE;
ScreenToFront(TekScreen);
mode = move;
}
return TekMode; /* i.e. if c== 29 we used it and can leave */
top:
/* first handle case if graph is sent without having the tek screen
* turned on; just eat the graphics commands until the graph is
* finished - then turn back to text mode
* also make this selanar compatible
*/
if(Tek_screen_open == 0) {
if((c == 24) || ((lastc == 27) && (c == 50)))
TekMode = FALSE; /* turn tek mode off */
lastc = c;
return TRUE;
}
/*
if(mode == alpha) {
emit(c);
emit(13);
emit(10);
}
*/
if (escmode)
{
if (colormode != (int)NULL) {
c = c - 48;
colormode++;
if (colormode == 2)
index = c;
else if (colormode == 3)
red = c;
else if (colormode == 4)
green = c;
else if (colormode == 5) {
COLOR((long)index, (long)red, (long)green, (long)c);
colormode = NULL;
escmode = FALSE;
}
return TekMode;
}
switch (c)
{
case '2': /* Selanar Compatable graphics terminator */
TekOFF();
boxmode = FALSE;
break;
/* I do not know what the tek 4100 area fill commands are so I made-up
my own, this will not harm the line drawing mode. */
case 'A':
boxmode = TRUE;
break;
case 'B':
boxmode = FALSE;
break;
case 'Q':
colormode = 1;
return TekMode;
/* another one of my own commands */
case 'R': /* reset to default then clear screen */
reset();
ic = 1;
case 12: /* clear page */
x = xmin;
y = ymin + dy;
mode = alpha;
tk4100 = NULL;
clear();
break;
case 'M': /* looks like a 4100 command */
tk4100 = 'M';
break;
}
escmode = FALSE;
}
else if (tk4100 != (int)NULL)
{
if (tk4100 == COLORSET)
ic = c - 48;
SetAPen(mrp, (long)ic);
if (tk4100 == 'M' && c == 'L')
tk4100 = COLORSET;
else
tk4100 = NULL;
}
else if (c >= 32)
if (mode == alpha)
{
if(xl > xmax-dx) xl = xmax-dx;
if(xl < xmin) xl = xmin;
if(yl < ymin+dy) yl = ymin+dy;
if(yl > ymax) yl = ymax;
SetAPen(mrp, 1L);
Move(mrp,(long)xl,(long)yl);
Text(mrp,&c,1L);
SetAPen(mrp, (long)ic);
xl += dx;
if (xl > xmax) xl = xmax;
}
else
{
/* a note here about 4014 graphics, If your graphics software
drives a Tek 4014 then this will work perfecly well, you
just will not be able to use the 4096 pixel resolution
that that big storage tube device offers */
register int tag, data, x, y;
tag = c/32;
data = c - tag*32;
switch (tag)
{
case 1:
if (last == 3)
hix = data*32;
else
hiy = data*32;
break;
case 2:
x = hix + data; /* low x always sent so don't save it */
y = hiy + loy;
if (t_scale == 0)
{
x = (((float)x)*xmax)/1024;
y = (((float)y)*ymax)/780;
}
x = x/(2-t_interlace);
y = (ymax-1) - (y/(2-t_interlace));
if(x > xmax) x = xmax;
if(x < xmin) x = xmin;
if(y > ymax) y = ymax;
if(y < ymin) y = ymin;
switch (mode)
{
case move:
mode = line;
Move(mrp, (long)x, (long)y);
break;
case line:
if (boxmode)
RectFill(mrp, (long)min((int)xl,(int)x),
(long)min((int)yl,(int)y), (long)max((int)xl,(int)x),
(long)max((int)yl,(int)y));
else
Draw(mrp, (long)x, (long)y);
break;
case point:
WritePixel(mrp, (long)x, (long)y);
break;
}
xl = x;
yl = y;
break;
case 3:
loy = data;
break;
}
last = tag;
}
else switch(c)
{
case 7: /* bell */
DisplayBeep(NULL);
break;
case 8: /* backspace */
x -= dx;
if (x < xmin) x = xmin;
break;
case 9: /* cursor right */
x += dx;
if (x > xmax) x = xmax;
break;
case 10: /* NL */
y += dy;
if (y > ymax) y = ymax;
break;
case 11: /* cursor up */
y -= dy;
if (y < ymin+dy) y = ymin+dy;
break;
case 13: /* CR */
x = xmin;
break;
case 24: /* CAN */
TekOFF();
boxmode = FALSE;
break;
case 27: /* ESC */
escmode = TRUE;
break;
case 28: /* FS (point-plot) */
mode = point;
break;
case 29: /* GS vector */
mode = move;
break;
case 31: /* alpha mode */
mode = alpha;
break;
default:
break;
} /* end of switch */
return TRUE;
}
reset()
{
/* mess up the colors */
COLOR(0L, 0L, 0L, 0L);
COLOR(1L, 15L, 15L, 15L);
COLOR(2L, 15L, 0L, 0L);
COLOR(3L, 0L, 15L, 0L);
COLOR(4L, 0L, 0L, 15L);
COLOR(5L, 0L, 15L, 15L);
COLOR(6L, 15L, 0L, 15L);
COLOR(7L, 15L, 15L, 0L);
COLOR(8L, 15L, 8L, 0L);
COLOR(9L, 8L, 15L, 0L);
COLOR(10L,0L, 15L, 8L);
COLOR(11L,0L, 8L, 15L);
COLOR(12L,8L, 0L, 15L);
COLOR(13L,15L, 0L, 8L);
COLOR(14L,5L, 5L, 5L);
COLOR(15L,10L, 10L, 10L);
clear();
SetAPen(mrp, 1L);
}
max(a,b)
int a,b;
{
if(a >= b) return(a);
return(b);
}
min(a,b)
int a,b;
{
if(a <= b) return(a);
return(b);
}
/*****************************************************************/
/* Intialize the structure arrays needed for
/* the Tek menu items
/*****************************************************************/
char keycommands[] = " TVEQ";
char otherkeys[] = "NY";
void
InitTekItems()
{
int n;
for(n=0; n<TekParamsMax; n++) {
TekItem[n].NextItem = &TekItem[n+1];
TekItem[n].LeftEdge = 0;
TekItem[n].TopEdge = 10 * n;
TekItem[n].Width = 100;
TekItem[n].Height = 10;
TekItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
TekItem[n].MutualExclude = 0;
TekItem[n].ItemFill = (APTR)&TekText[n];
TekItem[n].SelectFill = NULL;
TekItem[n].Command = 0;
TekText[n].FrontPen = 0;
TekText[n].BackPen = 1;
TekText[n].DrawMode = JAM2;
TekText[n].LeftEdge = 0;
TekText[n].TopEdge = 1;
TekText[n].ITextFont = NULL;
TekText[n].NextText = NULL;
}
TekItem[TekParamsMax - 1].NextItem = NULL;
TekText[0].IText = (UBYTE *)"Scale";
TekText[1].IText = (UBYTE *)"Screen Depth";
TekText[2].IText = (UBYTE *)"Interlace";
TekItem[0].SubItem = TekScaleItem;
TekItem[1].SubItem = TekDepthItem;
TekItem[2].SubItem = TekInterlaceItem;
for(n=0; n<TekScaleMax; n++) {
TekScaleItem[n].NextItem = &TekScaleItem[n+1];
TekScaleItem[n].LeftEdge = 60;
TekScaleItem[n].TopEdge = 10 * n;
TekScaleItem[n].Width = 100;
TekScaleItem[n].Height = 10;
TekScaleItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
TekScaleItem[n].MutualExclude = (~(1 << n));
TekScaleItem[n].ItemFill = (APTR)&TekScaleText[n];
TekScaleItem[n].SelectFill = NULL;
TekScaleItem[n].Command = 0;
TekScaleText[n].FrontPen = 0;
TekScaleText[n].BackPen = 1;
TekScaleText[n].DrawMode = JAM2;
TekScaleText[n].LeftEdge = 0;
TekScaleText[n].TopEdge = 1;
TekScaleText[n].ITextFont = NULL;
TekScaleText[n].NextText = NULL;
}
TekScaleItem[TekScaleMax - 1].NextItem = NULL;
switch(t_scale) {
case 0:
TekScaleItem[0].Flags |= CHECKED;
break;
case 1:
TekScaleItem[1].Flags |= CHECKED;
break;
}
TekScaleText[0].IText = (UBYTE *)" 1028x780";
TekScaleText[1].IText = (UBYTE *)" 640x400";
for(n=0; n<TekDepthMax; n++) {
TekDepthItem[n].NextItem = &TekDepthItem[n+1];
TekDepthItem[n].LeftEdge = 60;
TekDepthItem[n].TopEdge = 10 * n;
TekDepthItem[n].Width = 60;
TekDepthItem[n].Height = 10;
TekDepthItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
TekDepthItem[n].MutualExclude = (~(1 << n));
TekDepthItem[n].ItemFill = (APTR)&TekDepthText[n];
TekDepthItem[n].SelectFill = NULL;
TekDepthItem[n].Command = 0;
TekDepthText[n].FrontPen = 0;
TekDepthText[n].BackPen = 1;
TekDepthText[n].DrawMode = JAM2;
TekDepthText[n].LeftEdge = 0;
TekDepthText[n].TopEdge = 1;
TekDepthText[n].ITextFont = NULL;
TekDepthText[n].NextText = NULL;
}
TekDepthItem[TekDepthMax - 1].NextItem = NULL;
TekDepthText[0].IText = (UBYTE *)" 1";
TekDepthText[1].IText = (UBYTE *)" 2";
TekDepthText[2].IText = (UBYTE *)" 3";
TekDepthText[3].IText = (UBYTE *)" 4";
switch(t_depth) {
case 1:
TekDepthItem[0].Flags |= CHECKED;
break;
case 2:
TekDepthItem[1].Flags |= CHECKED;
break;
case 3:
TekDepthItem[2].Flags |= CHECKED;
break;
case 4:
TekDepthItem[3].Flags |= CHECKED;
break;
}
for(n=0; n<TekInterlaceMax; n++) {
TekInterlaceItem[n].NextItem = &TekInterlaceItem[n+1];
TekInterlaceItem[n].LeftEdge = 60;
TekInterlaceItem[n].TopEdge = 10 * n;
TekInterlaceItem[n].Width = 60;
TekInterlaceItem[n].Height = 10;
TekInterlaceItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT;
TekInterlaceItem[n].MutualExclude = (~(1 << n));
TekInterlaceItem[n].ItemFill = (APTR)&TekInterlaceText[n];
TekInterlaceItem[n].SelectFill = NULL;
TekInterlaceItem[n].Command = 0;
TekInterlaceText[n].FrontPen = 0;
TekInterlaceText[n].BackPen = 1;
TekInterlaceText[n].DrawMode = JAM2;
TekInterlaceText[n].LeftEdge = 0;
TekInterlaceText[n].TopEdge = 1;
TekInterlaceText[n].ITextFont = NULL;
TekInterlaceText[n].NextText = NULL;
}
TekInterlaceItem[TekInterlaceMax - 1].NextItem = NULL;
TekInterlaceText[0].IText = (UBYTE *)" Off";
TekInterlaceText[1].IText = (UBYTE *)" On";
switch(t_interlace) {
case 0:
TekInterlaceItem[0].Flags |= CHECKED;
break;
case 1:
TekInterlaceItem[1].Flags |= CHECKED;
break;
}
for(n=0; n<TekScreenMax; n++) {
TekScreenItem[n].NextItem = &TekScreenItem[n+1];
TekScreenItem[n].LeftEdge = 0;
TekScreenItem[n].TopEdge = 10 * n;
TekScreenItem[n].Width = 140;
TekScreenItem[n].Height = 10;
TekScreenItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP;
TekScreenItem[n].MutualExclude = 0;
TekScreenItem[n].ItemFill = (APTR)&TekScreenText[n];
TekScreenItem[n].SelectFill = NULL;
if(n != 0) {
TekScreenItem[n].Command = keycommands[n];
TekScreenItem[n].Flags |= COMMSEQ;
}
else
TekScreenItem[n].Command = 0;
TekScreenText[n].FrontPen = 0;
TekScreenText[n].BackPen = 1;
TekScreenText[n].DrawMode = JAM2;
TekScreenText[n].LeftEdge = 0;
TekScreenText[n].TopEdge = 1;
TekScreenText[n].ITextFont = NULL;
TekScreenText[n].NextText = NULL;
}
TekScreenItem[TekScreenMax - 1].NextItem = NULL;
TekScreenText[0].IText = (UBYTE *)" TekScreen";
TekScreenText[1].IText = (UBYTE *)" Tek Front";
TekScreenText[2].IText = (UBYTE *)" VT Front";
TekScreenText[3].IText = (UBYTE *)" Erase";
TekScreenText[4].IText = (UBYTE *)" Quit";
TekScreenItem[0].SubItem = TekSelectItem;
for(n=0; n<TekSelectMax; n++) {
TekSelectItem[n].NextItem = &TekSelectItem[n+1];
TekSelectItem[n].LeftEdge = 60;
TekSelectItem[n].TopEdge = 10 * n;
TekSelectItem[n].Width = 100;
TekSelectItem[n].Height = 10;
TekSelectItem[n].Flags = ITEMTEXT | ITEMENABLED | HIGHCOMP | CHECKIT
| COMMSEQ;
TekSelectItem[n].MutualExclude = (~(1 << n));
TekSelectItem[n].ItemFill = (APTR)&TekSelectText[n];
TekSelectItem[n].SelectFill = NULL;
TekSelectItem[n].Command = otherkeys[n];
TekSelectText[n].FrontPen = 0;
TekSelectText[n].BackPen = 1;
TekSelectText[n].DrawMode = JAM2;
TekSelectText[n].LeftEdge = 0;
TekSelectText[n].TopEdge = 1;
TekSelectText[n].ITextFont = NULL;
TekSelectText[n].NextText = NULL;
}
TekSelectItem[TekSelectMax - 1].NextItem = NULL;
/* switch(t_on) {
case 0:
TekSelectItem[0].Flags |= CHECKED;
break;
case 1:
TekSelectItem[1].Flags |= CHECKED;
break;
}
*/
TekSelectItem[t_on].Flags |= CHECKED;
TekSelectText[0].IText = (UBYTE *)" Off";
TekSelectText[1].IText = (UBYTE *)" On";
}
/****************************************************************/
/* The following function inits the Menu structure array with
/* the tek menu items
/****************************************************************/
void
InitTekMenu()
{
menu[4].NextMenu = &menu[5];
menu[4].LeftEdge = 300;
menu[4].TopEdge = 0;
menu[4].Width = 85;
menu[4].Height = 10;
menu[4].Flags = MENUENABLED;
menu[4].MenuName = "Tek params"; /* text for menu-bar display */
menu[4].FirstItem = &TekItem[0]; /* pointer to first item in list */
menu[5].NextMenu = NULL;
menu[5].LeftEdge = 390;
menu[5].TopEdge = 0;
menu[5].Width = 60;
menu[5].Height = 10;
menu[5].Flags = MENUENABLED;
menu[5].MenuName = "Screen"; /* text for menu-bar display */
menu[5].FirstItem = &TekScreenItem[0]; /* pointer to first item in list */
}
void
t_cmd_scale(n)
char *n;
{
t_scale = atoi(n);
}
void
t_cmd_depth(n)
char *n;
{
if(t_depth != atoi(n)) {
t_depth = atoi(n);
if(Tek_screen_open == 1) {
CloseTek();
TekNewScreen.Depth = t_depth;
OpenTek(mywindow->UserPort);
}
}
}
void
t_cmd_on(n)
char *n;
{
if(t_on != atoi(n)) {
t_on = atoi(n);
if(t_on == 0)
CloseTek();
else
OpenTek(mywindow->UserPort);
}
}
void
t_cmd_interlace(n)
char *n;
{
if(t_interlace != atoi(n)) {
t_interlace = atoi(n);
if(Tek_screen_open == 1) {
CloseTek();
if(t_interlace == 0)
TekNewScreen.ViewModes |= ~INTERLACE;
else
TekNewScreen.ViewModes |= INTERLACE;
OpenTek(mywindow->UserPort);
}
}
}
void
t_cmd_null(n)
char *n;
{ }
struct COMMAND {
void (*func)();
char *cname;
};
/********************** command tables *******************************/
static struct COMMAND Tekcmds[] = { /* initialization commands */
t_cmd_scale, "ts", /* set tek scale */
t_cmd_on, "to", /* set tek screen on or off */
t_cmd_interlace, "ti", /* set tek interlace on or off */
t_cmd_depth, "td", /* set tek screen depth */
t_cmd_null, NULL /* end of list */
};
exe_t_cmd(p,l)
char *p;
int l;
{
int i,l2;
/* search in the tek command list */
for (i=0; Tekcmds[i].func != cmd_null; ++i) {
l2 = strlen(Tekcmds[i].cname);
if (l >= l2 && strncmp(p, Tekcmds[i].cname, l2) == 0) {
(*Tekcmds[i].func)(next_wrd(p+l, &l));
return(TRUE);
}
}
}