[net.sources] Raster Tech filter for Super Plot

majka@ubc-vision.UUCP (Marc Majka) (04/30/86)

Due to popular demand, here is my Raster Tech filter for the Super Plot
package I posted last week.  *WARNING*  some hacking will be required to
make it compatible with your local configuration.  See the README file for
more details.

Cut, sh, hack, and have fun!

---
Marc Majka  -  UBC Laboratory for Computational Vision


- - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - -
#!/bin/sh
#
# shell archive - extract with /bin/sh
#
echo extracting file README
sed 's/^X//' > README <<'!FUNKY!STUFF!'
XHere is a plot filter for a Raster Tech 1/25.  Before you jump up and down,
XI must warn you that it will not just compile and run.  You are going to
Xhave to rewrite parts of the file rtec.c to get the filter routines talking
Xto your Raster Tech correctly.  Our local configuration here at UBC is so
Xstrange that I wrote this version of rtec.c for this distribution.  It
Xassumes that your RTEC is hanging on /dev/rtec on your machine, and that
Xyour device driver does LOTS of clever things, like converting to HEXACSII
Xif necessary, or padding with nulls, or whatever.  If this is not the case,
Xyou are going to have to include the appropriate code somewhere in the
Xneighbourhood of the RTwrite routine in rtec.c  
X
XThe filter requires the labels.c and driver.c code that was included in my
X"Super Plot" distribution in net.sources.
X
XGood Luck!
X
X---
XMarc Majka
!FUNKY!STUFF!
echo extracting file Makefile
sed 's/^X//' > Makefile <<'!FUNKY!STUFF!'
X# Makefile for rtplot
X
Xrtplot: rtplot.o rtplotfns.o driver.o labels.o rtec.o
X	cc -o rtplot rtplot.o rtplotfns.o driver.o labels.o rtec.o -lm
!FUNKY!STUFF!
echo extracting file rtplot.c
sed 's/^X//' > rtplot.c <<'!FUNKY!STUFF!'
X/*************************************************************/
X/*                                                           */
X/*  Copyright (c) 1985                                       */
X/*  Marc S. Majka - UBC Laboratory for Computational Vision  */
X/*                                                           */
X/*  Permission is hereby granted to copy all or any part of  */
X/*  this program for free distribution.   The author's name  */
X/*  and this copyright notice must be included in any copy.  */
X/*                                                           */
X/*************************************************************/
X
X#include <stdio.h>
X
Xmain (argc, argv)
Xint argc;
Xchar *argv[];
X{
X    FILE *pfp, *fopen();
X    int argn, sqr, plt, win, ovr;
X    int x1, y1, x2, y2, r1, c1, r2, c2;
X    
X    sqr = 0;
X    win = 0;
X    plt = 0;
X    ovr = 0;
X    
X    for (argn = 1; argn < argc; argn++) {
X        if (argv[argn][0] == '-') {
X            switch (argv[argn][1]) {
X                case 'v': sqr = 1; break;
X                case 'o': ovr = 1; break;
X                case 'w':
X                    win = argn;
X                    r1 = atoi(argv[++win]);
X                    c1 = atoi(argv[++win]);
X                    r2 = atoi(argv[++win]);
X                    c2 = atoi(argv[++win]);
X                    x1 = c1 - 256;
X                    y1 = 255 - r1;
X                    x2 = c2 - 256;
X                    y2 = 255 - r2;
X                    win = 1;
X                    argn += 4;
X                    break;
X                default:
X                    fprintf(stderr,"rtplot [file] [-w r1 c1 r2 c2][-v][-o]\n");
X                    exit(0);
X            }
X        }
X        else {
X             if (plt) {
X                fprintf(stderr,"rtplot [file] [-w r1 c1 r2 c2][-v][-o]\n");
X                exit(0);
X            }
X            plt = 1;
X            pfp = fopen(argv[argn],"r");
X            if (pfp == NULL) {
X                fprintf(stderr,"can't open plot file %s\n",argv[argn]);
X                exit(1);
X            }
X        }
X    }
X
X    if (!plt) pfp = stdin;
X
X    plotopen();
X
X    if (sqr) {
X        x1 = -256; y1 =  255;
X        x2 =  229; y2 = -230;
X    } 
X    
X    if (win || sqr) {
X        frame(x1,y1,x2,y2,1);
X        space(x1,y1,x2,y2,1);
X    }
X    
X    if (!ovr) {
X        RTvalue(0,0,0);
X        RTclear();
X        RTvalue(255,255,255);
X    }
X
X    plotdriver(pfp);
X    plotclose();
X    exit(0);
X}
!FUNKY!STUFF!
echo extracting file rtplotfns.c
sed 's/^X//' > rtplotfns.c <<'!FUNKY!STUFF!'
X/*************************************************************/
X/*                                                           */
X/*  Copyright (c) 1985                                       */
X/*  Marc S. Majka - UBC Laboratory for Computational Vision  */
X/*                                                           */
X/*  Permission is hereby granted to copy all or any part of  */
X/*  this program for free distribution.   The author's name  */
X/*  and this copyright notice must be included in any copy.  */
X/*                                                           */
X/*************************************************************/
X
X#include <math.h>
X#include <stdio.h>
X#include <sgtty.h>
X#include <signal.h>
X
X#define FPMAX 32
X#define MAXPATS 128
X
Xstruct fpstruct {
X    char grid[FPMAX][FPMAX];
X    int nr, nc;
X};
X
Xstruct fpstruct fpat[MAXPATS];
X
X#define MAXVERT 32767
X
Xstatic short fstack[MAXVERT][2], knotn, knotk;
Xstatic int ftop;
X
Xstruct plstruct {
X    double x1, y1, x2, y2;      /* min and max points       */
X    double xr, yr;              /* x and y range            */
X    double xc, yc;              /* current point            */
X    int uhv;                    /* user hv                  */
X    int ubpp;                   /* user bits per pixel      */
X    double ubppr;               /* user bpp range           */
X    int patc;                   /* current fill pattern     */
X    int r1, c1, r2, c2;         /* max and min row and col  */
X    int rr, cr;                 /* row and col range        */
X    int rc, cc;                 /* current row and col      */
X    int dhv;                    /* device hv                */
X    int dbpp;                   /* image bits per pixel     */
X    double dbppr;               /* image bpp range          */
X    int fill, fstat;            /* fill mode                */
X} impl;
X
Xmove(x1,y1)
Xint x1,y1;
X{
X    rtscale(x1,y1);
X
X    if ((impl.fill) && (impl.fstat)) {
X        fstack[ftop][0] = (short)impl.rc;
X        fstack[ftop][1] = (short)impl.cc;
X        ftop++;
X        impl.fstat = 0;
X    }
X    else RTmovabs(impl.rc,impl.cc);
X}
X
Xcont(x1,y1)
Xint x1,y1;
X{
X    rtscale(x1,y1);
X
X    if (impl.fill) {
X        fstack[ftop][0] = (short)impl.rc;
X        fstack[ftop][1] = (short)impl.cc;
X        ftop++;
X        if (ftop > MAXVERT) {
X            fprintf(stderr,"plrt: polygon stack overflow\n");
X            exit(1);
X        }
X    }
X    else RTdrwabs(impl.rc,impl.cc);
X}
X
Xline(x1,y1,x2,y2)
Xint x1,y1,x2,y2;
X{
X    move(x1,y1);
X    cont(x2,y2);
X}
X
Xchain(n,v)
Xshort n,*v;
X{
X    int i, p;
X    short x, y;
X
X    p = 0;
X    x = v[p++]; y = v[p++];
X    move(x,y);
X    
X    for (i = 1; i < n; i++) {
X        x = v[p++]; y = v[p++];
X        cont(x,y);
X    }
X}
X
Xbspline(k,n,v)
Xshort k,n,*v;
X{
X    double u, du, ufin, x, y;
X    short nn;
X    
X    nn = n - 1;
X    ufin = (double)(nn - k + 2);
X    du = ufin / (500.0 + (double)nn);
X    
X    u = 0.0;
X    Bpoint(&x,&y,0.0,nn,k,v);
X    rtdscale(x,y);
X    RTmovabs(impl.rc,impl.cc);
X    
X    while (u <= ufin) {
X        u = u + du;
X        Bpoint(&x,&y,u,n,k,v);
X        rtdscale(x,y);
X        RTdrwabs(impl.rc,impl.cc);
X    }
X
X    x = v[nn*2];
X    y = v[nn*2 + 1];
X    cont((short)x,(short)y);
X}
X
XBpoint(x,y,u,n,k,v)
Xdouble *x,*y,u;
Xint n,k;
Xshort *v;
X{
X    int i, m;
X    double b, Bnblend();
X    
X    *x = 0.0; *y = 0.0;
X    m = 0;
X    knotk = k;
X    knotn = n;
X
X    for (i = 0; i <= n; i++) {
X        b = Bnblend(i,k,u);
X        *x = *x + (double)(v[m]) * b;
X        *y = *y + (double)(v[m+1]) * b;
X        m += 2;
X    }
X}
X
XBknot(i)
Xint i;
X{
X    if (i < knotk) return(0);
X    else if (i > knotn) return(knotn - knotk + 2);
X    else return(i - knotk + 1);
X}
X
Xdouble Bnblend(i,k,u)
Xint i,k;
Xdouble u;
X{
X    double v, v1, v2, t1, t2, abs();
X    
X    v1 = 0.0; v2 = 0.0; t1 = 0.0; t2 = 0.0;
X    
X    if (k == 1) {
X        if ((Bknot(i) <= u) && (u < Bknot(i+1))) v = 1.0;
X        else v = 0.0;
X    }
X    else {
X        t1 = Bknot(i+k-1) - Bknot(i);
X        if (t1 != 0) v1 = (u - Bknot(i)) * Bnblend(i,k-1,u) / t1;
X
X        t2 = Bknot(i+k) - Bknot(i+1);
X        if (t2 != 0) v2 = (Bknot(i+k) - u) * Bnblend(i+1,k-1,u) / t2;
X        
X        v = v1 + v2;
X    }
X    return(v);
X}
X
Xpolygon(n,v)
Xshort n,*v;
X{
X    short vn, nverts[2], indx, x, y;
X
X    nverts[0] = n;
X    
X    RTmovabs(0,0);
X    RTprmfil(1);
X    RTpolyhdr(1,nverts);
X    
X    indx = 0;
X    for (vn = 0; vn < n; vn++) {
X        x = v[indx++]; y = v[indx++];
X        rtscale(x,y);
X        RTpolypt((short)impl.rc,(short)impl.cc);
X    }
X
X    RTprmfil(0);
X}
X
Xmoverel(x1,y1)
Xint x1,y1;
X{
X    impl.xc += x1; impl.yc += y1;
X    move((int)impl.xc,(int)impl.yc);
X}
X
Xcontrel(x1,y1)
Xint x1,y1;
X{
X    impl.xc += x1; impl.yc += y1;
X    cont((int)impl.xc,(int)impl.yc);
X}
X
Xdblmoverel(x1,y1)
Xdouble x1,y1;
X{
X    impl.xc += x1; impl.yc += y1;
X    rtdscale(impl.xc,impl.yc);
X    RTmovabs(impl.rc,impl.cc);
X}
X
Xdblcontrel(x1,y1)
Xdouble x1,y1;
X{
X    impl.xc += x1; impl.yc += y1;
X    rtdscale(impl.xc,impl.yc);
X    RTdrwabs(impl.rc,impl.cc);
X}
X
Xpoint(x1,y1)
Xint x1,y1;
X{
X    rtscale(x1,y1);
X
X    RTmovabs(impl.rc,impl.cc);
X    RTpoint();
X}
X
Xarc(xc,yc,x1,y1,x2,y2)
Xint xc,yc,x1,y1,x2,y2;
X{
X    double fabs(), hypot(), acos(), cos(), sin();
X    double dt, a1, a2, theta, rad, pi, pi2, up, dn, bup, bdn;
X    double cx, cy;
X    int catch;
X    
X    pi = acos(-1.0);
X    pi2 = 2.0 * pi;
X
X    /* Algorithm: move to x1 y1. The angle between x1 y1 and the x axis is a1.
X        The angle to x2 y2 is a2. Set theta = a1, and move to x1 y1.
X        Sweep anti-clockwise to a2, incrementing theta by dt. At each step,
X        find the point on the arc at angle theta. Use cont to draw a line
X        to that point.
X    */
X
X    rad = hypot((double)(x1-xc),(double)(y1-yc));
X    
X    /* find the angles a1 and a2 */
X    
X    if (y1 >= yc) a1 = acos((x1-xc)/rad);
X    else a1 = pi + acos((xc-x1)/rad);
X
X    if (y2 >= yc) a2 = acos((x2-xc)/rad);
X    else a2 = pi + acos((xc-x2)/rad);
X    
X    move(x1,y1);
X    
X    dt = 5.0 / rad;
X    theta = a1;
X    up = a2+dt;
X    dn = a2-dt;
X    bup = up + pi2;
X    bdn = dn + pi2;
X    catch = 0; /* safety chain */
X
X    /* step around the arc until within range of a2 */
X    while (!((catch > 1) && (((theta < up) && (theta > dn)) ||
X        ((theta < bup) && (theta > bdn))))) {
X
X        impl.xc = xc + rad * cos(theta);
X        impl.yc = yc + rad * sin(theta);
X
X        if (impl.uhv != impl.dhv) {
X            impl.cc = impl.c1 + (impl.xc - impl.x1) * (impl.cr / impl.xr);
X            impl.rc = impl.r1 + (impl.yc - impl.y1) * (impl.rr / impl.yr);
X        }
X        else {
X            impl.rc = impl.r1 + (impl.xc - impl.x1) * (impl.rr / impl.xr);
X            impl.cc = impl.c1 + (impl.yc - impl.y1) * (impl.cr / impl.yr);
X        }
X        
X        RTdrwabs(impl.rc,impl.cc);
X        theta+=dt;
X        
X        /* safety check to catch runaway loops */
X        if (catch++ > 1000000) {
X            fprintf(stderr,"arc: runaway loop caught: inform a wizard!\n");
X            fprintf(stderr,"  xc=%lf yc=%lf x1=%lf y1=%lf x1=%lf y1=%lf\n",
X                xc,yc,x1,y1,x2,y2);
X            fprintf(stderr,"  angle1=%lf angle2=%lf dtheta=%lf\n",a1,a2,dt);
X            exit(1);
X        }
X    }
X
X    /* finish up */
X    cont(x2,y2);
X    point(x2,y2);
X}
X
Xcircle(x1,y1,r)
Xint x1,y1,r;
X{
X    arc(x1, y1, x1-r, y1, x1-r, y1);
X}
X
Xlinemod(str)
Xchar *str;
X{
X    int x1, x2, i;
X
X    x1 = 0;
X    x2 = 0;
X    for (i = 15; i >= 0; i--) {
X        if (str[x2++] == '1') x1 |= 1<<i;
X        if (str[x2] == '\0') x2 = 0;
X    }
X    RTvecpat(x1);
X}
X
Xerase()
X{
X    RTclear();
X}
X
Xarea(x1,y1)
Xint x1,y1;
X{
X    move(x1,y1);
X    RTarea1();
X}
X
Xstartp()
X{
X    impl.fill = 1;
X    impl.fstat = 1;
X    ftop = 0;
X}
X
Xendp()
X{
X    short nverts[2];
X
X    nverts[0] = ftop;
X
X    impl.fill = 0;
X    impl.fstat = 0;
X    RTmovabs(0,0);
X    RTprmfil(1);
X    RTpolygn(1,nverts,fstack);
X    ftop = 0;
X    RTprmfil(0);
X}
X
Xbppout(b)
Xint b;
X{
X    impl.dbpp = b;
X    impl.dbppr = (1 << b) - 1;
X}
X
Xbppin(b)
Xint b;
X{
X    impl.ubpp = b;
X    impl.ubppr = (1 << b) - 1;
X}
X
Xgray(g)
Xint g;
X{
X    int ng;
X    
X    ng = (int)((double)g * impl.dbppr/impl.ubppr);
X    RTvalue(ng,ng,ng);
X}
X    
Xcolour(r,g,b)
Xint r,g,b;
X{
X    double dr, dg, db;
X
X    dr = (double)r * impl.dbppr/impl.ubppr;
X    dg = (double)g * impl.dbppr/impl.ubppr;
X    db = (double)b * impl.dbppr/impl.ubppr;
X
X    RTvalue((int)dr,(int)dg,(int)db);
X}
X
Xpensize(n)
Xshort n;
X{
X/* PENSIZE NOT IMPLEMENTED */
X}
X
Xfillpat(n,r,c,str)
Xint n,r,c;
Xchar *str;
X{
X    int i, j, p;
X
X    if (n >= MAXPATS) {
X        fprintf(stderr,"fillpat: pattern number %d > max %d\n",n,MAXPATS-1);
X        exit(1);
X    }
X    
X    impl.patc = n;
X    
X    fpat[n].nr = r;
X    fpat[n].nc = c;
X    p = 0;
X    
X    for (i = 0; i < r; i++)
X        for (j = 0; j < c; j++) {
X            if (str[p++] == '1') fpat[n].grid[i][j] = 1;
X            else fpat[n].grid[i][j] = 0;
X            if (str[p] == '\0') p = 0;
X        }
X}
X
Xsetpat(n)
Xint n;
X{
X    impl.patc = n;
X}
X
Xframe(x1,y1,x2,y2,hv)
Xint x1,y1,x2,y2,hv;
X{
X    impl.r1 = x1; impl.c1 = y1;
X    impl.r2 = x2; impl.c2 = y2;
X    impl.rr = x2 - x1; 
X    impl.cr = y2 - y1; 
X    impl.dhv = hv;
X}
X
Xspace(x1,y1,x2,y2,hv)
Xint x1,y1,x2,y2,hv;
X{
X    impl.x1 = x1; impl.y1 = y1;
X    impl.x2 = x2; impl.y2 = y2;
X    impl.xr = x2 - x1; 
X    impl.yr = y2 - y1; 
X    impl.uhv = hv;
X    if (impl.xr == 0) impl.xr = 1;
X    if (impl.yr == 0) impl.yr = 1;
X}
X
Xrtscale(x,y)
Xint x,y;
X{
X    impl.xc = x; impl.yc = y;
X    
X    if (impl.uhv != impl.dhv) {
X        impl.cc = impl.c1 + (impl.xc - impl.x1) * (impl.cr / impl.xr);
X        impl.rc = impl.r1 + (impl.yc - impl.y1) * (impl.rr / impl.yr);
X    }
X    else {
X        impl.rc = impl.r1 + (impl.xc - impl.x1) * (impl.rr / impl.xr);
X        impl.cc = impl.c1 + (impl.yc - impl.y1) * (impl.cr / impl.yr);
X    }
X}
X
Xrtdscale(x,y)
Xdouble x,y;
X{
X    impl.xc = x; impl.yc = y;
X    
X    if (impl.uhv != impl.dhv) {
X        impl.cc = (int)(0.5 + (double)impl.c1 + 
X            (impl.xc - impl.x1) * ((double)impl.cr / impl.xr));
X        impl.rc = (int)(0.5 + impl.r1 +
X            (impl.yc - impl.y1) * ((double)impl.rr / impl.yr));
X    }
X    else {
X        impl.rc = (int)(0.5 + impl.r1 +
X            (impl.xc - impl.x1) * ((double)impl.rr / impl.xr));
X        impl.cc = (int)(0.5 + impl.c1 +
X            (impl.yc - impl.y1) * ((double)impl.cr / impl.yr));
X    }
X}
X
Xplotopen()
X{
X    RTinit();
X    RTentgra();
X
X    /* defaults */
X    frame(-256,255,255,-256,1);
X    space(-256,255,255,-256,1);
X    bppin(8);
X    bppout(8);
X    move(0,0);
X    linemod("1");
X    font("sr");
X    fspec(1.0,1.0,0.0);
X    gray(255);
X    impl.fill = 0;
X    impl.fstat = 0;
X
X    /* AT THIS POINT, INSERT WHATEVER YOU WANT TO RESET THE RTEC */
X	RTwrmask(255,31);
X}
X
Xplotclose()
X{
X    RTfini();
X}
X
Xcomment(str)
Xchar *str;
X{
X}
X
Xdonelabel()
X{
X}
!FUNKY!STUFF!
echo extracting file rtec.c
sed 's/^X//' > rtec.c <<'!FUNKY!STUFF!'
X/********************************************************************/
X/*                                                                  */
X/* This file contains a set of routines called by rtplot. The first */
X/* three, RTinit, RTwrite, and RTfini, must be replaced by routines */
X/* which accomplish the same  thing for your Raster Tech in your    */
X/* local configuration.                                             */
X/*                                                                  */
X/* The routines below the dotted line are independent the local     */
X/* configuration.  This setup may be inefficient, but it is as      */
X/* general as I can make it.                                        */
X/*                                                                  */
X/* The moral of the story is that you are going to hack around in   */
X/* this file to get the RTEC filter going on your system.           */
X/*                                                                  */
X/********************************************************************/
X
X#include <stdio.h>
X
X#define ENTERGRAPHICS 4
X#define AREA1 19
X#define CLEAR 135
X#define DRWABS 129
X#define MOVABS 1
X#define POINT 136
X#define POLYGN 18
X#define PRMFIL 31
X#define VALUE 6
X#define VECPAT 46
X#define WRMASK 157
X
X/* CHANGE THIS TO POINT IN THE RIGHT DIRECTION */
X#define RTEC_DEVICE "/dev/rtec"
X
Xstatic FILE *rtfp;
Xstatic char rtbuf[1024];
X
XRTinit()
X{
X    FILE *fopen();
X    rtfp = fopen(RTEC_DEVICE,"w");
X}
X
XRTfini()
X{
X    fclose(rtfp);
X}
X
XRTwrite(buf,len)
Xchar *buf;
Xint len;
X{
X    /* you may need to convert to HEXASCII, or pad with nulls
X       or otherwise fool around in here */
X
X    fwrite(buf,len,1,rtfp);
X}
X
XRTentgra()
X{
X    rtbuf[0] = ENTERGRAPHICS;
X    RTwrite(rtbuf,1);
X}
X
X/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
X
XRTarea1()
X{
X    rtbuf[0] = AREA1;
X    RTwrite(rtbuf,1);
X}
X
XRTclear()
X{
X    rtbuf[0] = CLEAR;
X    RTwrite(rtbuf,1);
X}
X
XRTdrwabs(x,y)
Xshort x,y;
X{
X    rtbuf[0] = DRWABS;
X    rtbuf[1] = (char)((x>>8)&255);
X    rtbuf[2] = (char)(x&255);
X    rtbuf[3] = (char)((y>>8)&255);
X    rtbuf[4] = (char)(y&255);
X    RTwrite(rtbuf,5);
X}
X
XRTmovabs(x,y)
Xshort x,y;
X{
X    rtbuf[0] = MOVABS;
X    rtbuf[1] = (char)((x>>8)&255);
X    rtbuf[2] = (char)(x&255);
X    rtbuf[3] = (char)((y>>8)&255);
X    rtbuf[4] = (char)(y&255);
X    RTwrite(rtbuf,5);
X}
X
XRTpoint()
X{
X    rtbuf[0] = POINT;
X    RTwrite(rtbuf,1);
X}
X
XRTpolygn(npoly,nverts,vals)
Xshort npoly,*nverts,*vals;
X{
X    int polyn, vertn, nvals, nbuf;
X
X    rtbuf[0] = POLYGN;
X    rtbuf[1] = npoly;
X    RTwrite(rtbuf,2);
X
X    nbuf = 0;
X
X    for (polyn = 0; polyn < npoly; polyn++) {
X        nvals = nverts[polyn] * 2;
X        rtbuf[nbuf++] = (char)((nverts[polyn] >> 8) & 255);
X        rtbuf[nbuf++] = (char)(nverts[polyn] & 255);
X
X        for (vertn = 0; vertn < nvals; vertn++) {
X            rtbuf[nbuf++] = (char)((vals[vertn] >> 8) & 255);
X            rtbuf[nbuf++] = (char)(vals[vertn] & 255);
X        }
X        RTwrite(rtbuf,nbuf);
X    }
X        
X}
X
XRTpolyhdr(npoly,nverts)
Xshort npoly,*nverts;
X{
X    int polyn, vertn, nvals, nbuf;
X    
X    rtbuf[0] = POLYGN;
X    rtbuf[1] = npoly;
X    
X    nbuf = 0;
X    
X    for (polyn = 0; polyn < npoly; polyn++) {
X        nvals = nverts[polyn] * 2;
X        rtbuf[nbuf++] = (char)((nverts[polyn] >> 8) & 255);
X        rtbuf[nbuf++] = (char)(nverts[polyn] & 255);
X    }
X    RTwrite(rtbuf,nbuf);
X}
X
XRTpolypt(x,y)
Xshort x,y;
X{
X    rtbuf[0] = (char)((x >> 8) & 255);
X    rtbuf[1] = (char)(x & 255);
X    rtbuf[2] = (char)((y >> 8) & 255);
X    rtbuf[3] = (char)(y & 255);
X    RTwrite(rtbuf,4);
X}
X
XRTprmfil(flag)
Xshort flag;
X{
X    rtbuf[0] = PRMFIL;
X    rtbuf[1] = flag;
X    RTwrite(rtbuf,2);
X}
X
XRTvalue(r,g,b)
Xshort r,g,b;
X{
X    rtbuf[0] = VALUE;
X    rtbuf[1] = r;
X    rtbuf[2] = g;
X    rtbuf[3] = b;
X    RTwrite(rtbuf,4);
X}
X
XRTvecpat(mask)
Xshort mask;
X{
X    rtbuf[0] = VECPAT;
X    rtbuf[1] = (char)((mask >> 8) & 255);
X    rtbuf[2] = (char)(mask & 255);
X    RTwrite(rtbuf,3);
X}
X
XRTwrmask(bitm,bankm)
Xshort bitm,bankm;
X{
X	rtbuf[0] = WRMASK;
X	rtbuf[1] = bitm;
X	rtbuf[2] = bankm;
X	RTwrite(rtbuf,3);
X}
!FUNKY!STUFF!
echo Done\!
exit 0