/* 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 1024x790 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 graphis input mode and run time selection * of the screen resoultion. */ /* compiler directives to fetch the necessary header files */ #include "vt100.h" #include "graphics/display.h" /* this varaible conditionally compiles in one of 2 modes, * if TS = 1 you get a 16 color 640x400 screen, the system can not * manage to draw sucessfully at 19200 bps in this mode, and the screen * on the Amiga 1080 monitor flickers like crazy. (any one know a better * monitor for interlace, i.e. one with longer persistance) * TS = 2 gives 320x200 32 color screen. It would be simple to put in * 6 bit planes to allow extra half bright, but for displaying color * graphs that mode is not usefull. This mode runs at 19200 bps. */ #define TS 1 /* global pointers, used only in this code module */ struct Screen *TekScreen; struct Window *TekWindow; int *TekFillRas; extern int * AllocRaster(); /* 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, 0); /* set the screen to color Zero */ /* the screen size */ #define xmin 0 #define ymin 0 #define xmax (640/TS) #define ymax (400/TS) struct NewScreen TekNewScreen = { xmin, ymin, xmax, ymax, 3 + TS, 0, 1, #if TS == 2 NULL , #else HIRES|INTERLACE, #endif CUSTOMSCREEN, NULL, NULL, NULL, NULL }; struct NewWindow TekNewWindow = { xmin, ymin, xmax, ymax, -1, -1, RAWKEY, /* No IDCMP flags */ BORDERLESS|NOCAREREFRESH|SMART_REFRESH, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, CUSTOMSCREEN }; /* initalise the window and screen needed for this mode * inituition and gfx are assumed open */ InitTek(HisPort) struct MsgPort *HisPort; { static struct AreaInfo ai; static WORD buffer[250]; static struct TmpRas tr; TekScreen = (struct Screen *)OpenScreen(&TekNewScreen); if (TekScreen == NULL) return TRUE; TekNewWindow.Screen = TekScreen; TekWindow = (struct Window *)OpenWindow(&TekNewWindow); if (TekWindow == NULL) 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, 100); mrp->AreaInfo = &ai; TekFillRas = AllocRaster(xmax, ymax); mrp->TmpRas = InitTmpRas(&tr, TekFillRas, RASSIZE(xmax, ymax)); reset(); TekScale = 1; TekOFF(); return FALSE; /* no errors detected */ } CloseTek() { TekMode = FALSE; FreeRaster(TekFillRas, xmax, ymax); TekWindow->UserPort = NULL; /* I will not close his port */ CloseWindow(TekWindow); CloseScreen(TekScreen); } /************************************************* * 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 short x = xmin, xl; static short y = ymin + dy, yl; static int last, escmode = FALSE, boxmode = FALSE; static short loy, hix, hiy; static enum {alpha, line, move, point} mode; static colormode = NULL, index, red, green; #define COLORSET 1024 static int tk4100 = NULL; static int ic = 1; if (TekMode) goto top; if (c == 29) { TekMode = TRUE; ScreenToFront(TekScreen); mode = move; } return TekMode; /* i.e. if c== 29 we used it and can leave */ top: if (escmode) { if (colormode != 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(index, red, green, c); colormode = NULL; escmode = FALSE; } return TekMode; } switch (c) { case '2': /* Selanar Compatable graphics termiante */ 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 != NULL) { if (tk4100 == COLORSET) ic = c - 48; SetAPen(mrp, ic); if (tk4100 == 'M' && c == 'L') tk4100 = COLORSET; else tk4100 = NULL; } else if (c >= 32) if (mode == alpha) { SetAPen(mrp, 1); Move(mrp,xl,yl); Text(mrp,&c,1); SetAPen(mrp, 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 (TekScale == 0) { x = (x*xmax)/1024; y = (y*ymax)/780; } x = x/TS; y = ((ymax-1) - y/TS); switch (mode) { case move: mode = line; Move(mrp, x, y); break; case line: if (boxmode) RectFill(mrp, min(xl, x), min(yl, y), max(xl, x), max(yl, y)); else Draw(mrp, x, y); break; case point: WritePixel(mrp, x, 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(0, 00, 00, 00); COLOR(1, 15, 15, 15); COLOR(2, 15, 00, 00); COLOR(3, 00, 15, 00); COLOR(4, 00, 00, 15); COLOR(5, 00, 15, 15); COLOR(6, 15, 00, 15); COLOR(7, 15, 15, 00); COLOR(8, 15, 08, 00); COLOR(9, 08, 15, 00); COLOR(10,00, 15, 08); COLOR(11,00, 08, 15); COLOR(12,08, 00, 15); COLOR(13,15, 00, 08); COLOR(14,05, 05, 05); COLOR(15,10, 10, 10); clear(); SetAPen(mrp, 1); }