! "W N, R=    @ #D  D ҃TP  B ы e@W 0 ,"& 7   0ߋp@E A Ze      |@7x@ eE "  ɋ -lɋ e-RNHɋ ^?megapp.ax : megsrc.ax z_7Mlibm.axXwEg0emdb.cx #include #include main(argc,argv) int argc; char *argv[]; { register int cur,n; int i1 , i2; int tmp[2] , cmd; int exit(); if( (Mioptr=fopen(MEGDEV,"r+w")) == NULL ) { printf("\n Cannot open /dev/meg ! \n\7"); exit(1); } if ((Mpioptr=fopen(MEGPDEV,"r+w")) == NULL ) { printf("\n Cannot open /dev/megper ! \n\7"); exit(1); } cur = 0; putw(0177761,Mioptr); putw(05,Mioptr); putw(0,Mioptr); Mflush(); signal(SIGQUIT,exit); signal(SIGINT,0); for(;;){ signal(SIGINT,0); printf("\n? "); read_line(&cmd , &i1 , &i2); n = 1; switch(cmd) { case '\n': cur++; break; case '=': /* replace current word */ putw(cur,Mioptr); putw(i1,Mioptr); putw(i2,Mioptr); Mflush(); continue; case '-': if(i1) cur -= i1; else cur--; break; case 'q': exit(0); case '/': cur = tmp[1]; break; case '+': cur += i1; break; case 0: if(i1) cur = i1; break; case 'p': if(i1) n = i1; break; case 'z': if(i1 == 0) i1 = 050; while( i1>0){ n = (i1>50)? 50:i1; i1 -= n; putw(cur,Mioptr); cur += n; for(;n>0;n--){ putw(0, Mioptr); putw(0, Mioptr); } Mflush(); } continue; default: ; } for(;n>0;n--){ tmp[0] = cur; read(fileno(Mioptr),tmp,4); printf("\n%6o\t%6o %6o", cur++, tmp[0], tmp[1]); } cur--; } printf("\n"); exit(0); msetup(); /* dummy call to insure loading of globals */ } /* * read and parse a line: */ read_line(cp , i1p , i2p) int *cp; int *i1p , *i2p; { char line[30] , *rcp1; register char *rcp , c; rcp = &line[0]; while( (*rcp++ = getchar()) != '\n'); *rcp++ = '\n'; *rcp = '\n'; if( (*cp= line[0])<'0' || line[0]>'7' ) /* he did give a non-octal command */ rcp1 = &line[1]; else{ rcp1 = &line[0];/* otherwise gave a memory location */ *cp = 0; } *i1p = atoo( &rcp1 ); *i2p = atoo( &rcp1 ); } /* * read an octal number: */ atoo( cpp ) char **cpp; { register char *rcp , c; register int num; rcp = *cpp; num = 0; while(*rcp++ == ' ') ; rcp--; while( (c= *rcp++)>='0' && c<='7' ) { num=* 8; num=+ (c-'0'); } *cpp = rcp; /* points to char after the terminator */ return(num); } /* * draw sierpinski curves on the megatek */ #define n 5 /* order of the curve */ #define h0 2048 /* resolution */ #define X 1 #define Y 0 int pos0[2],pos[2]; main() { register int h , i , j; float fh; float m[4][4]; float offset; msetup(); mseg(1); ident(m); offset = -h0/2; mtrans(m,offset,offset,0.); mscale(m,2.0,2.0,2.0); mxform(1,m); h = h0/4; pos0[X]=2*h; pos0[Y] = 3*h; offset = -h0/2; for(i=1;i<=n;i++){ pos0[X] -= h; h = h/2; pos0[Y] += h; pos[X] = pos0[X]; pos[Y] = pos0[Y]; mplot(pos[X],pos[Y],3); curve(i,X,Y,h,h); line(X,Y,h,-h); curve(i,Y,X,-h,h); line(X,Y,-h,-h); curve(i,X,Y,-h,-h); line(X,Y,-h,h); curve(i,Y,X,h,-h); line(X,Y,h,h); } mxform(1,m); sleep(3); for(j=0;j<110;j++){ mrotate(m,0.,0.,5.); mscale(m,0.96,0.96,0.96); mxform(1,m); } mblank(1); } line(d1,d2,h1,h2) { pos[d1] += h1; pos[d2] += h2; mplot(pos[X],pos[Y],2); } curve(j,d1,d2,h1,h2) register int j , h1 , h2; { if(j>0){ curve(j-1,d1,d2,h1,h2); line(d1,d2,h1,-h2); curve(j-1,d2,d1,-h2,h1); /* rotate -pi/2 */ line(d1,d2,2*h1,0); curve(j-1,d2,d1,h2,-h1); /* rotate +pi/2 */ line(d1,d2,h1,h2); curve(j-1,d1,d2,h1,h2); } } b52.editxJK-+$$+-+$$+e;e8e0#e#0e8e;e8e0e#eeeeeeeee#e0e8=:1$$1:=:1$$1:=:1$$1:=:1$$1:{={:{1${$1{:{={:{1{${{{{{{{{{${1{:-=-:-1$-$1-:-=-:-1-$---------$-1-:=:1$$1:=:1$$1:=:1$$1:=:1$$1:C=C:C1$C$1C:C=C:C1C$CCCCCCCCC$C1C:=:1$$1:=:1$$1:=:1$$1:=:1$$1:Y<Y9Y1#Y#1Y9Y<Y9Y1Y#YYYYYYYYY#Y1Y9 9 7 ." ". 7 9 7 . "   " . 741**141**1o.o,o%o%o,o.o,o%ooooooooooo%o,!)!' !"!"! '!)!'!"!! !!!!!!! !!"!'%#  #%# #     77777777777777777777oWq7qplATT/;p;)33 dd*o*W7pA/p) {TTT{:TV:VTVVXXXX            ! ! ""!##"$$#%%$&&%''&((')))(*++*,,+--,..-//.00/1102213324 435!546"657#768$879%98:&:9;';:<(<;=)=*=<>*?+?>@,@?A-A@B.BAC/CBD0DCE1EDF2FEG3GFH4HGI5IHJ6JIK7KJL8LKM9MLN:NMO;ONP<POQ=Q>QPR>S?SRT@TSUAUTVBVUWCWVXDXWYEYXZFZY[G[Z\H\[]I]\^J^]_K_^`L`_aMa`bNbacOcbdPdceQeRedfRgSgfhThgiUihjVjikWkjlXlkmYmlnZnmo[onp\poq]qpr^rqs_srt`tsuautvbvuwcwvxdxwyeyfyxzf{g{z|h|{}i}|~j~}k~lmnopqrstuvwxyzz{|}~                     ! ! ""!##"$$#%%$&&%''&(('))(**)++*,,+---,.//.00/1102213324 435!546"657#768$879%98:&:9;';:<(<;=)=<>*>=?+?>@,@?A-A.A@B.C/CBD0DCE1EDF2FEG3GFH4HGI5IHJ6JIK7KJL8LKM9MLN:NMO;ONP<POQ=QPR>RQS?SRT@TSUAUBUTVBWCWVXDXWYEYXZFZY[G[Z\H\[]I]\^J^]_K_^`L`_aMa`bNbacOcbdPdceQedfRfegSgfhThgiUiVihjVkWkjlXlkmYmlnZnmo[onp\poq]qpr^rqs_srt`tsuautvbvuwcwvxdxwyeyxzfzy{g{z|h|{}i}j}|~j~k~~~l~m~n~o~p~q~r~s~t~u~v~w~x~y~z~{~|~}f16.editxx4 0000000 0000000000000$0)0,0,0+ 0%000 0 &,047. #   (.288+ EC>7*)4*-7 >CE+N+K+E+<+/++ +++++++++ ++#+++2+7+8+8+) +.+:/+0<+#E+K+NLJE;/ "*27886<:/0;#EJLuIuGuBu8u+uuuuuuuuuuu uuu'u1u:u:u8u<u:u5+u-8u!BuGuIED?5( (2888851(+5 ?DE<><=<8<0<%<<<<<<<<<<< <<<'> >!>=?"?>@#@$@?A%A&A'A@B(BAC)CBD*DCE*EDF+FEG,GFH-HGI.IHJ/JIK/KJL0LKM1ML2MN2NNO2ONO3OOP4POQ5QPR6RQS7SRT8TSU9UTV:VUW;WVX<XWY=YXZ>ZY[?[@[Z\A\[]B]\^C^]_D_^`E`_aFa`bGbacHcbdIdceJedfKfefLffgMgfNghNiOihjPjQjikRkjlRlSlkmTmlRURmSUTVXXYYZZ_]`^a_b_c`n`ncoaobonpcpoqcqdqprerfrqsfsgshsrthtsuiutvjvuwkwvxlxwymyxzRzy{S{T{z|U|{}V}|~V~}W~XYZZ[\]^__`abcnopqrttuvwxyz{|}~                !! ""!##"$$#%%$   %& ' '&( (') )(* *)+ +*,,,+--,..-//.00/110221332443554665776887998::9;;:<<;== =<>!>=?"?>@#@?A$A@B%BA&&&BC&D&DCE'EDF(FEG)GFH*HGI+IHJ,JIK-KJL.LKM/MLN0NMO1ONP2POQ3QPR4R5RQS6SRT7TSU8UTV9VUW:WVX;XWY<YXZ=ZY[>[Z\?\[]@]\^A^]_B_^CCC_`C`D`E`F`G`H`I`J`K`L`M`N`O`P`Q`R`S`T`U`V`W`X`Y`Z`[`\`]`^`_bacadbdcecfdfegehfhgjikiljlkmknlnmompnporqsqtrtsvuwuxvxw>=?"?>@#@?A$A@B%BA&&&BC&D&DCE'EDF(FEG)GFH*HGI+IHJ,JIK-KJL.LKM/MLN0NMO1ONP2POQ3QPR4R5RQS6SRT7TSU8UTV9VUW:WVX;XWY<YXZ=ZY[>[Z\?\[]@]\^A^]_B_^CCC_`C`D`E`F`emsetup.cv x # /* * setup global variables and open megatek */ #include char *Maddr; /* 7000's current address */ char *Mhaddr; /* 7000's main header address */ FILE *Mioptr; /* 7000's file pointer */ FILE *Mpioptr; /* 7000's peripherals file ptr */ char Mbuffer[MBUFSIZE]; /* buffer */ int Mfree; /* index into first free block */ int Mseg; /* the current segment number */ int Mrot; /* rotation for strings */ int Mscale; /* scale factor for characters */ int Mintsty; /* current intensity */ int Mpackflag; /* whether to increase Maddr when flushing buffer */ int Meventvalue; /* the last value seen by mevent */ struct seg_struct Msegs[MAXSEG+1]; struct save_struct Msave[MAXSEG+1]; struct block_struct Mblock[NBLOCKS]; int Mrts[2*BLOCKSIZE+1]; msetup() { register int j , *ip; register char *addr; int v[3]; if( Mioptr != NULL) /* already did setup */ return(0); if ( (Mioptr = fopen(MEGDEV,"r+w")) == NULL ) Gerror("Cannot open %s\n",SYSTEM,MEGDEV); setbuf(Mioptr , Mbuffer); if( (Mpioptr = fopen(MEGPDEV,"r+w")) == NULL ) Gerror("Cannot open %s\n",SYSTEM,MEGPDEV); /*fill the rts block structure */ ip = &Mrts[1]; for(j=0; j MAXSEG) Gerror("%s -- Illegal seg \"%d\"\n",FATAL,routine,seg); if ( (b=Msegs[ai].start) == 0) Gerror("%s -- Seg %d not defined\n",FATAL,routine,ai); if ( b < 0 ) Gerror("%s -- Invalid operation on sub %d\n",FATAL,routine,ai); return(b); } Mputw(x) { register int b; register struct seg_struct *segptr; segptr = &Msegs[Mseg]; if ( segptr->nleft-- <= 3 ){ b = segptr->end; b = Mblock[b].next = Mgetfree(); if ( b<=0) Gerror("Out of free blocks !",SYSTEM); segptr->nleft = PACKCOUNT; Maddr = Mblock[b].addr; Mpackflag = 0; /* jump to the next block */ Mput32( JMP, Maddr); mflush(); segptr->end = b; putw( Maddr , Mioptr); }else if (Mioptr->_cnt == MBUFSIZE ) putw( Maddr, Mioptr); putw( x , Mioptr); Mpackflag++; } mflush() { register FILE *iop; register char *base; register int n; iop = Mioptr; if( (base = iop->_base) != NULL && (n = iop->_ptr - base) > 0){ if ( Mpackflag ) { Maddr += (PACKCOUNT - Msegs[Mseg].nleft)/2; if(Msegs[Mseg].start == Msegs[Mseg].end) Maddr -= HDRSIZE; } Mpackflag = 0; /* don't change Maddr */ iop->_ptr = base; iop->_cnt = MBUFSIZE; /* bytes */ if( write(fileno(iop),base,n) != n) Gerror("mflush --bad write count ",SYSTEM); } } tmseg.c x  # /* * open a megatek segment: * * seg header: * +0 nop or an rts (for blank) * +1 dash pattern * +2 blink pattern * +3 color * +4-11 8 matrix elements * +12 matrix transformation control * +13 set absolute z * +14 blink enable/disable * +15 intensity * +16-? display (terminated with a RTS) * * */ #include mseg(i) { register int b , ai; register struct seg_struct *segptr; char *addr; if((ai=abs(i)) > MAXSEG) Gerror("mseg -- seg no. out of range \"%d\"",FATAL,ai); if( Mioptr == NULL) Gerror("Setup not called yet!",FATAL); if(ai == 0){ Mioptr == NULL; msetup(); return(0); } /* close last segment */ if(Mseg){ segptr = &Msegs[Mseg]; segptr->curx = ML.xcur; segptr->cury = ML.ycur; segptr->curz = ML.zcur; } /* be sure not jumping to this seg from the main header: */ mflush(); putw(Mhaddr+ai, Mioptr); Mput32( NOP, 0); mflush(); segptr = &Msegs[ai]; /* delete old seg */ if( (b=segptr->end)!=0 ) { Mblock[b].next = Mfree; /* link back into free list */ Mfree = segptr->start; segptr->start = segptr->end = Msave[ai].start = Msave[ai].end = 0; Mseg = 0; } if( i<0 ) return; /* only wanted to destroy it */ /* init a new seg: */ b = segptr->start = segptr->end = Mgetfree(); addr = Mblock[b].addr; /* start of seg */ Mblock[b].next = -1; /* this block not linked */ putw(addr, Mioptr); /* start send to this addr */ Mput32( NOP , 0); Mput32( 0160010 , 052525 ); /* default dash pattern */ Mput32( 0160011 , 1); /* default blink pattern */ Mput32( 0160252 , 0167); /* set color */ Mident(); /* fill 8 matrix elements with identity */ Mput32( 0160013 , 0040000); /* set matrix transform control on */ Mput32( 0177000 , 010000 ); /* set z origin */ Mput32( 0 , 0 ); /* no blinking */ Mput32( NOP | 037 , 0); /* set intensity */ Mput32( RTS, 0); /* first word in display list is a return */ mflush(); putw(Mhaddr+ai, Mioptr); /* replace nop in big header with a jsr */ Mput32( JSR, addr); mflush(); Mseg = ai; Maddr = addr + HDRSIZE; segptr->nleft = PACKCOUNT - 2*HDRSIZE + 1; Mintsty = 017; ML.xcur = ML.ycur = ML.zcur = 0; /* start at (0,0,0) */ Mputw( 0154000 );Mputw( 044000 ); /* set clipping to full screen */ Mputw( 0153777 );Mputw( 0143777 ); } mplot.cMx y# /* * enter a 2D coord to the megatek (use current z!): */ #include mplot(x,y,pen) register int x,y; { register struct Glocal *MLp; int flags; if(Mseg == 0) Gerror("mplot -- No seg or sub open",FATAL); MLp = &ML; flags = 0; if( MLp->relabs==ABSOLUTE ){ x -= MLp->xcur; y -= MLp->ycur; } MLp->xcur += x; MLp->ycur += y; x &= 07777; y &= 07777; if( pen < 0 ){ pen = (-pen); MLp->xcur = 0; MLp->ycur = 0; } switch(pen) { case 0: break; case 2: dosolid: flags = 0100000; /* no break */ case 3: Mputw( 0140000 | x); Mputw( 0050000 | y | flags); break; case 4: Mputw( 060000 | x); Mputw( (Mintsty<<12) | y ); Mputw( 040000 ); Mputw( Mintsty<<12 ); break; case 5: Mputw( 0140000 | x); Mputw( 0110000 | y ); break; default: Gerror("Invalid pen code \"%d\"",WARNING,pen); goto dosolid; } } 7mblink.cx # /* * blink or unblink a seg: */ #include mblink(i) { register int b; register char *addr; b = Mseg_ok(i, "mblink"); addr = Mblock[b].addr + 14; mflush(); putw( addr , Mioptr); Mput32( ((i>0)? 010000: 00000) , 0 ); mflush(); } mblank.cx "# /* * blank or unblank a seg: */ #include mblank(i) { register int b; register char *addr; b = Mseg_ok(i,"mblank"); addr = Mblock[b].addr; mflush(); /* put a NOP or RTS in this seg's header block */ putw(addr,Mioptr); Mput32( ((i>0)? RTS: NOP) , 0); mflush(); } mdim.cx A# /* * set the initial intensity for a seg: */ #include mdim(i,ints) { register int b , flag; register char *addr; b = Mseg_ok(i,"mdim"); addr = Mblock[b].addr + 15; ints=& 017; /* max intensity is 15 */ Mintsty = ints; mflush(); putw(addr,Mioptr); Mput32( NOP | 020 | ints , 0 ); mflush(); } ammove.c7x D# /* * move a seg to x,y */ #include mmove(seg , x , y) { register int b; register char *addr; int tmp[2]; b = Mseg_ok(seg, "mmove"); addr = Mblock[b].addr + 6; mflush(); putw( addr , Mioptr); Mput32( 0160002 , x); mflush(); addr += 3; putw( addr , Mioptr); Mput32( 0160005 , y); mflush(); } Mgetfree.cNx Y# /* * return with the index of the next free Mblock: */ #include Mgetfree() { register int f; if( (f=Mfree) < 0 ) Gerror(" out of free blocks!",SYSTEM); Mfree = Mblock[f].next; Mblock[f].next = -1; Mrts[0] = Mblock[f].addr; /* fill the block with rts's */ write(fileno(Mioptr), Mrts, 4*BLOCKSIZE + 2); return(f); } }Mmsend.cOx y# /* * send a transformation matrix: * matrix is of the form: * * * __ __ * [x y 0 1]' = [x y z 1] * | m1 m4 ? 0 | * | m2 m5 ? 0 | * | m7 m8 ? 0 | * | m3 m6 ? 1 | * -- -- * * tricky: elements m3 and m6 are sent as 16-bit signed integers. * all others are sent by multiplying them by 2048 and converting * to a signed integer!(obviously) * */ #include /* m1 m2 m3 m4 m5 m6 m7 m8 */ int Morder[] {0 , 4 , 12 , 1 , 5 , 13 , 8 , 9}; Mmsend(m) float *m; /* a 4x4 floating matrix */ { register float *rm; register int i , j; float f; int *ip; ip = &f; rm=m; for(j=0;j<8;j++) { putw( 0160000 | j , Mioptr); f = rm[ Morder[j] ]; if( j!=2 && j!=5 ) /* ie, not m3 or m6 */ *ip=+ 02600; /* "f=* 2048." */ putw( (i=f+0.5) , Mioptr); } } iMident.cOx c# /* * set the given 4x4 matrix to identity: */ float Midentity[] { 1.,0.,0.,0. , 0.,1.,0.,0. , 0.,0.,1.,0. , 0.,0.,0.,1.}; ident(m) float *m; { register int *f1 , *f2; register int j; f1 = &Midentity[0]; f2 = m; j=32; while(j--) *f2++ = *f1++; } /* * send an identity matrix to the megatek: */ Mident() { Mmsend( &Midentity[0] ); } +mintsty.cPx # /* * set subsequent megatek intensities (0-15): */ #include mintsty(i) register int i; { if (Mseg == 0) Gerror(" mintsty -- no seg open ", FATAL); i &= 017; Mintsty = i; Mputw( NOP | 020 | i ); Mputw( 0 ); } 7mset.cPx # /* * mset - set display parameters for the megatek */ #include mset (string, value) char *string; register int value; { register int b; register char *addr; int op , option , n; option = Gsearch(string); switch (option) { case SETSCL: if (value < 0 || value > 7) { Gerror ("mset - scale factor out of range \"%d\"", WARNING, value); break; } Mscale = value; break; case SETROT: if(value < 0 || value > 3) { Gerror ("mset - text rotation out of range \"%d\"", WARNING,value); break; } Mrot = value; break; case SETBLINK: op = 0160011; value &= 017; n = 2; goto sendit; case SETDASH: op = 0160010; n = 1; sendit: if ( Mseg < 0 ){ Gerror("mset -- no open seg ",WARNING); return; } b = Msegs[Mseg].start; addr = Mblock[b].addr + n; mflush(); putw( addr , Mioptr ); Mput32( op , value ); mflush(); break; case SETERR: Glevel = value; break; case SETABS: ML.relabs = ABSOLUTE; break; case SETREL: ML.relabs = RELATIVE; break; default: Gerror ("mset -- illegal option ignored \"%s\"\n", WARNING, string); break; } } Smxform.cQx # /* * change the transformation matrix in the header of seg #seg */ #include mxform( seg, m) float *m; { register char *addr; register int b; b = Mseg_ok(seg); addr = Mblock[b].addr + 4; mflush(); putw( addr, Mioptr); Mmsend(m); mflush(); } 3mappend.cx # /* * re-open a seg */ #include mappend(i) { register int b , ai; register struct seg_struct *segptr; if(Mseg){ /* close last seg */ segptr = & Msegs[Mseg]; segptr->curx = ML.xcur; segptr->cury = ML.ycur; segptr->curz = ML.zcur; } mflush(); /* make sure buffer is empty */ if( (ai=abs(i)) == 0 || ai>MAXSEG) Gerror("mappend -- seg or sub number out of ramge",FATAL); if( i<0 ) /* append to a sub */ ai = MAXSEG+1 -ai; Mseg = ai; Mseg = ai = abs(i); segptr = &Msegs[ai]; b = segptr->end; Maddr = Mblock[b].addr + (PACKCOUNT - segptr->nleft + 1)/2; ML.xcur = segptr->curx; ML.ycur = segptr->cury; ML.zcur = segptr->curz; } mcursor.cx W# /* * attach this seg to the joystick * (does a mmove(i,x,y) before displaying sub ) */ #include mcursor(i) { register int b; register char *addr; b = Mseg_ok(i, "mcursor"); addr = Mblock[b].addr + 14; mflush(); putw( addr , Mioptr); if( i>0 ){ Mput32( JSR , JOYTRACK ); }else{ Mput32( 0 , 0 ); } mflush(); } smdir.cx T# /* * read joystick directions and return -3,-2,-1,0,1,2,3: */ #include int Mcnvrt[] { -3 , -2 , -1 , 0 , 0 , 1 , 2 , 3}; mdir(dx , dy) int *dx , *dy; { register int i; int tmp[2]; mflush(); tmp[0] = JOYSTICK; Mread( &tmp[0] , 4); i = tmp[1]; /* joystick byte */ *dx = Mcnvrt[(i>>3)&07]; *dy = Mcnvrt[i&07]; } mevent.cx # /* * wait for any peripheral to be struck and return its word: */ #include mevent() { register int v0, Mpfd; int v[3]; mflush(); /* empty the buffer */ Mpfd = fileno(Mpioptr); v[2] = 0; v[0] = WAIT; stty(Mpfd , v); gtty(Mpfd , v); v0 = v[0]; v[0] = v[2] = 0; stty(Mpfd , v); Meventvalue = 0377 & v0; if( v0 & KEYFLAG) return( 1 ); if( v0 & JOYFLAG ) return( 4 ); if( v0 & TABLETFLAG ) return( 8 ); return( 0 ); } smgetsub.cSx 1# /* * insert a "jsr sub#i" into the display list of the current seg. * * DANGER: this can blow up if sub#i is later deleted!! * */ #include mgetsub(i) { register char *addr; register int b , ai; if((ai=abs(i)) == 0 || ai > MAXSEG) Gerror("mgetsub -- sub no. out of range \"%d\"",FATAL,ai); if ( (b=(-Msegs[ai].start)) <= 0) Gerror("mgetsub -- \"%d\" is not a sub",FATAL,ai); if( Mseg <= 0 ) Gerror("mgetsub -- No open segment",FATAL); addr = Mblock[b].addr; Mputw( JSR ); Mputw( addr ); /* to first display command */ } tmgetxy.cx # /* * read the megatek joystick and return those coordinates: * (Tricky: read local tracker instead of x and y registers!) */ #include mgetxy(xp , yp , button) int *xp , *yp , *button; { register int j; int tmp[2]; mflush(); /* make sure buffer is empty */ tmp[0] = JOYTRACK; /* hide megatek address in array */ Mread( &tmp[0] , 4); for(j=0; j<=1; j++) { tmp[j]=& 07777; /* strip blank vector codes */ if( tmp[j]&04000 ) /* sign extend if necessary */ tmp[j]=| 0170000; } *xp = tmp[0]; *yp = tmp[1]; /* now pick up the button */ tmp[0] = JOYSTICK; /* hide megatek address in array */ Mread( &tmp[0] , 4); if( tmp[1]&0100 ) *button = 1; else *button = 0; Meventvalue = 0; } mkeybrd.cTx f# /* * read the megatek keyboard: */ #include mkeybrd(iflag) { register int v0, Mfd; int v[3]; Mfd = fileno(Mpioptr); mflush(); /* make sure buffer is empty */ if(v0=Meventvalue) return(v0); else for(;;) { gtty(Mfd , v); if( (v0=v[0]) == 0 ) return(0); if( v0&KEYFLAG ) return(v0&0377); } Meventvalue = 0; } mmark.c1x # /* * Msave the current state of the current seg: */ #include mmark() { register struct seg_struct *segptr; register struct save_struct *saveptr; register int seg; seg = Mseg; if( seg <=0 ) Gerror(" mark -- seg not open",FATAL); mflush(); saveptr = &Msave[seg]; segptr = &Msegs[seg]; saveptr->header[0] = Mblock[ segptr->start ].addr; /* read the current file header from the Megatek */ Mread( &Msave[ seg ].header[0] , 4 * HDRSIZE); saveptr->nleft = segptr->nleft; saveptr->start = segptr->start; saveptr->end = segptr->end; saveptr->relflag = ML.relabs; saveptr->curx = ML.xcur; saveptr->cury = ML.ycur; saveptr->curz = ML.zcur; } mplot3.cUx # /* * enter a 3D coordinate to the megatek * (coords are in integer and in the range -+2048) */ #include mplot3(x,y,z,pen) register int x,y,z; { int setnewz; if( Mseg <= 0 ) Gerror("mplot3 -- no open seg or sub",FATAL); if ( pen == 5 ){ /* kludge a point plot */ mplot3( x-1 , y-1 , z-1 , 3 ); mplot3( x , y , z , 2 ); return(0); } /* set new z */ setnewz = 0; if( ML.relabs==RELATIVE ){ if ( z != 0 ) setnewz++; }else /* absolute vectors */ if ( z != ML.zcur ) { setnewz++; z -= ML.zcur; } if(setnewz){ ML.zcur += z; Mputw( 0177100 ); Mputw( 0010000 | z); } if( pen < 0 ){ pen = (-pen); ML.zcur = 0; } /* and do a 2-D plot */ mplot( x , y , pen ); } mreset.cUx ;# /* * return a seg to its previously marked state: */ #include mreset() { int j , k , seg; register int *addr; register struct seg_struct *segptr; register struct save_struct *saveptr; seg = Mseg; if( seg<=0 ) Gerror("reset - seg not open",FATAL); segptr = &Msegs[seg]; saveptr = &Msave[seg]; j = saveptr->end; if( j<=0 ) Gerror(" reset without a mark",FATAL); /* link leftover blocks back into the free list: */ if( Mblock[j].next>0 ) { Mblock[ segptr->end ].next = Mfree; Mfree = Mblock[j].next; } Mblock[j].next = -1; segptr->end = j; segptr->nleft = saveptr->nleft; ML.xcur = saveptr->curx; ML.ycur = saveptr->cury; ML.zcur = saveptr->curz; ML.relabs = saveptr->relflag; Maddr = addr = Mblock[j].addr + (PACKCOUNT - segptr->nleft + 1)/2; mflush(); putw( addr , Mioptr); k = (segptr->nleft)/2; for(j=0;jstart ].addr; /* seg header */ putw(addr, Mioptr); addr = &(saveptr->header[0]); for(j=0; j<2*HDRSIZE; j++) putw( *addr++ , Mioptr); mflush(); } pmstrget.cVx # /* * obtain a string from the Megatek keyboard: * * The given prompt is placed at the coordinates given. * Reading continues until see a CR. * Only "max" characters allowed to be read into "array". * */ #define DEL 0177 #define BKSP 010 #define CR 015 #define KBWAIT 01 /* keyboard event occurred */ mstrget(x , y , prompt , max , array) char *prompt , *array; { register char *cp , c; cp = array; *cp = '\0'; mmark(); c = DEL; do { switch( c ) { case DEL: cp = array; *cp = '\0'; break; case BKSP: if( cp == array ) break; *--cp = '\0'; break; default: if( cp < &array[max-1] ) { *cp++ = c; *cp = '\0'; }else{ mreset(); return(0); } } mreset(); mplot(x,y,3); mstring(prompt); mstring(array); mflush(); while( (KBWAIT & mevent()) == 0) /* wait */; } while( (c=mkeybrd()) != CR); mreset(); } rmstring.cVx # /* * draw a string at current location */ #define BUFLEN 200 #include mstring(format,args) char *format; { register char *rcp; register int word , count; char string[BUFLEN]; int setstring; if(Mseg==0) Gerror("mstring -- no open seg or sub",FATAL); Gsprintf(string,format,&args); setstring = 0170000 |(Mscale<<4) | (Mrot<<7); rcp = string; Mputw(setstring); ML.xcur += (12*(1+Mscale)*strlen(string)); count = 2; do{ if(Msegs[Mseg].nleft == 5){ Mputw(0); Mputw(0); Mputw(setstring); count = 2; } count++; word = (*rcp++)<<8; if(*rcp){ count++; word |= *rcp++; } Mputw( word ); } while(*rcp); count &= 03; if(count==0) Mputw( 0 ); if(count != 03) Mputw( 0 ); } mvport.c˾x # /* * set the screen window on the megatek: * (coords are -+ 2048) */ #include mvport(xl,yb,xr,yt) { if( Mseg == 0 ) Gerror("mvport -- no open seg or sub",FATAL); xl=& 07777; yb=& 07777; xr=& 07777; yt=& 07777; Mputw( 0150000 | xl ); Mputw( 040000 | yb ); Mputw( 0150000 | xr ); Mputw( 0140000 | yt ); ML.lvp.xl = xl; ML.lvp.yb = yb; ML.lvp.xr = xr; ML.lvp.yt = yt; } *msub.cWx # /* * open a megatek sub: */ #include msub(i) { register int b , ai; register struct sub_struct *subptr; char *addr; if((ai=abs(i)) == 0 || ai > MAXSEG) Gerror("msub -- sub no. out of range \"%d\"",FATAL,ai); /* close last subment */ if(Mseg){ subptr = &Msegs[Mseg]; subptr->curx = ML.xcur; subptr->cury = ML.ycur; subptr->curz = ML.zcur; } ai = MAXSEG+1 - ai; subptr = &Msegs[ai]; /* delete old sub */ if( (b=subptr->end)!=0 ) { Mblock[b].next = Mfree; /* link back into free list */ Mfree = abs(subptr->start); subptr->start = subptr->end = Msave[ai].start = Msave[ai].end = 0; Mseg = 0; } if( i<0 ) return; /* only wanted to destroy it */ /* init a new sub: */ subptr->end = b = Mgetfree(); subptr->start = (-b); Mblock[b].next = -1; /* this block not linked */ Mseg = ai; Maddr = Mblock[b].addr; subptr->nleft = PACKCOUNT; ML.xcur = ML.ycur = ML.zcur = 0; /* start at (0,0,0) */ ML.lvp.xl = ML.lvp.yb = -2048; /* initial viewport */ ML.lvp.xr = ML.lvp.yt = 2047; } mrotate.cXx # /* * apply a rotation to matrix m * order: ax,ay,az in degrees */ #define DTOR 0.017453 mrotate(m,ax,ay,az) float ax,ay,az, m[4][4]; { float m1[4][4]; Mrotm(m1,ax,ay,az); mmult(m,m1,m); } /* * make m a rotation matrix for concatenation with */ Mrotm(m,ax,ay,az) float ax,ay,az, m[4][4]; { float sx,cx,sy,cy,sz,cz,sin(),cos(); ax *= DTOR; ay *= DTOR; az *= DTOR; if (ax == 0.0 ) { sx=0.0; cx=1.0; } else { sx=sin(ax); cx=cos(ax); } if (ay == 0.0 ) { sy=0.0; cy=1.0; } else { sy=sin(ay); cy=cos(ay); } if (az == 0.0 ) { sz=0.0; cz=1.0; } else { sz=sin(az); cz=cos(az); } m[0][0]= cy*cz; m[0][1]= cy*sz; m[0][2]= -sy; m[0][3]= 0.; m[1][0]= -cx*sz + sx*sy*cz; m[1][1]= cx*cz + sx*sy*sz; m[1][2]= sx*cy; m[1][3]= 0.; m[2][0]= cx*sy*cz +sx*sz; m[2][1]= cx*sy*sz -sx*cz; m[2][2]= cx*cy; m[2][3]= 0.; m[3][0]= 0.; m[3][1]= 0.; m[3][2]= 0.; m[3][3]= 1.; } imtrans.cXx 4/* * apply a translation to matrix m */ mtrans(m,sx,sy,sz) float sx,sy,sz, m[4][4]; { float m1[4][4]; Mtransm(m1,sx,sy,sz); mmult(m,m1,m); } /* * create a translation matrix for concatenation */ Mtransm(m,tx,ty,tz) float tx,ty,tz, m[4][4]; { ident(m); m[3][0]= tx; m[3][1]= ty; m[3][2]= tz; } mscale.cYx &# /* * apply a scaling to m */ mscale(m,sx,sy,sz) float sx,sy,sz, m[4][4]; { float m1[4][4]; Mscalem(m1,sx,sy,sz); mmult(m,m1,m); } /* * set up a scaling matrix for concatenation */ Mscalem(m,sx,sy,sz) float sx,sy,sz, m[4][4]; { ident(m); m[0][0]= sx; m[1][1]= sy; m[2][2]= sz; } mcopy.cYx # #include "megatek.h" /* * copy matrix 1 to matrix 2: */ mcopy(m1,m2) float *m1 , *m2; { register int *rm1 , *rm2 , n; rm1 = m1; rm2 = m2; n = 32; while( n-- ) *rm2++ = *rm1++; } smnumget.cZx B# /* * mnumget - input a decimal or octal no. from the megatek */ #include #define MAXNUM 30 /* max. no. of input digits */ double mnumget (x, y, prompt, maxdig, flag) int x,y; /* x, y loc. for the input */ int maxdig; /* max. no. of input digits */ int *flag; /* return code: =0 no errors =1 invalid input syntax =2 no input received */ char *prompt; /* prompt string */ { char buffer[MAXNUM]; /* input buffer */ double input; /* input number */ double atof1(); /* convert char to no. */ /* get the character input */ if (maxdig > MAXNUM || maxdig <= 0) { Gerror ("mnumget - max. no. of input digits invalid - %d assumed", WARNING, MAXNUM); maxdig = MAXNUM; } mstrget (x, y, prompt, maxdig, buffer); input = atof1(buffer, flag); return (input); } mdata.cZx 6# /* * mdata - initialize structures for the Megatek graphics package */ #include struct Gworld MW = { 0.0,0.0,0.0, 0.0,0.0,0.0, 1.0, {-6.,-6.,-6.,6.,6.,6.}, }; struct Glocal ML = { 0, 0, 0, {-2048,-2048,2047,2047}, {-2048,-2048,2047,2047}, {-6.,-6.,6.,6.}, "megatek", ABSOLUTE, }; mend.c[x i# /* * close the megatek */ #include mend() { mflush(); fclose(Mioptr); Mioptr = 0; } doitx ?cc -c -O $1.c ar rv /lib/libm.a $1.o rm $1.o echo Done with $1 mtialize structures for the Megatek graphics package */ #include struct Gworld MW = { 0.0,0.0,0.0, 0.0,0.0,0.0, 1.0, emappend.o x *Dw Wp Be N %  !N Wp Bed rWt@l7d^Z VwNmappend -- seg or sub number out of ramge   (h(   _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mappend"~_mappencsv _i_b_ai_segptr_Mseg L4*_Msegs _ML _mflush _abs L10000@L5NL6_Gerror L7\_Mblock _Maddr cret mblank.ox \w \f t   @ & wmblank   I_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mblank"~_mblankcsv _i_b_addrL4\_Mseg_ok _Mblock _mflush _Mioptr _putw L10000>L10001Bcret mblink.oAx ^w ^f te   & & wmblink   I_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mblink"~_mblinkcsv _i_b_addrL4^_Mseg_ok _Mblock _mflush _Mioptr _putw L10000BL10001Dcret mcursor.ox pw pf te    E & & wmcursor     I_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mcursor"~_mcursocsv _i_b_addrL4p_Mseg_ok _Mblock _mflush _Mioptr _putw L5PL20001bcret mdim.ox dw df teEw  fU & wmdim)9H9H9H)Y_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mdim"~_mdimcsv _i_ints_b_flag_addrL4d_Mseg_ok _Mblock _Mintsty _mflush _Mioptr _putw cret mdir.ox Tw  Bfe& %DtE =TE =Tw_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Mcnvrt#T_mdir"~_mdircsv _dx_dy_i_tmp_mflush _Mioptr _read cret mnumget.oDx 8\w &%   % Nef fff eN fe ffffpnljw`mnumget - max. no. of input digits invalid - %d assumed8HXiiiiiiiiy_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mnumget"~_mnumgecsv _x_y_prompt_maxdig _flag _buffer_inputL10000L4.L5_Gerror _mstrget _atof1 ac0 cret fltused faddzfsubzfmulzfdivzmstrget.okx  hw D Õ7~ yD ff %N N 5 %  wD- $@ @m !Ԑ n r$|yIXhhyII_mstrget"L10001L10002L10rL9$L11|~_mstrgecsv _x_y_prompt_max _array _cp_c_mmark L6L10003L20000(L7*_mreset _mplot _mstring _mflush L14T_mevent _mkeybrd L3ncret L12mevent.ox ,w  5 Ne Ne D 55Ne E75 w5@5   Y_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mevent"~_meventcsv _v0_Mpfd_v_mflush _Mpioptr _stty _gtty _Meventv L4zL3vL20001lL20003rcret mgetsub.ox v^Dw N % v %Wp A C %  t  wmgetsub -- sub no. out of range "%d"mgetsub -- "%d" is not a submgetsub -- No open segment(Y_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mgetsub"~_mgetsucsv _i_addr_b_ai_abs L10000L4&L5v_Gerror _Msegs L6FL7_Mseg L8ZL9_Mblock _Mputw cret mgetxy.o5x lw  Efe& %  @aE @a5 @aU %}}Bfe& %5@= 7 `w\Yi_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mgetxy"~_mgetxycsv _xp_yp_button_j_tmp_mflush _Mioptr _read L20001.L6TL8L9_Meventv cret mhvport.o x hw f te EEE E & fU fU@ f U |f U jwfmhvport(9IXIXIXIXIX9i_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mhvport"~_mhvporcsv _seg_xl_yb_xr _yt _addr_bL4_Mseg_ok _Mblock _Mflush _Mioptr _putw cret mintsty.ox 8w D 8 E7U  w mintsty -- no seg open  _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mintsty"~_mintstcsv _i_Mseg L4L58_Gerror _Mintsty _Mputw cret mkeybrd.ox Fw  Ne D 5Ew(I_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mkeybrd"~_mkeybrcsv _iflag_v0_Mfd_v_Mpioptr _mflush _Meventv L5L3B_gtty L76cret mmark.ox p w  WpNCeWp Det3@WpNef& %3 3  wv mark -- seg not open (8IXiiiiy_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mmark"~_mmarkcsv _segptr_saveptr_seg_Mseg L4L5_Gerror _mflush _Msave _Msegs _Mblock _Mioptr _read _ML cret mmove.o!x 8w f te   f e  f zwvmmove)9H9H9H)9H9H9H)Y_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mmove"~_mmovecsv _seg_x_y_b_addr_tmpL4_Mseg_ok _Mblock _mflush _Mioptr _putw cret mplot3.ox Pw DCB  %   & e& e 15 %  - `z@ U @ 5 7 TN & %w>mplot3 -- no open seg or subIIIII_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mplot3"~_mplot3csv _x_y_z_pen _setnewz_Mseg L4&L5_Gerror L6\L3_ML L7rL9L11_Mputw L12_mplot cret mplot.oix >w DC  5 ( a`EE @ 5 2 @ " xU` t P @ pt U UN %U @]UP w"jmplot -- No seg or sub openInvalid pen code "%d"Y_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mplot"L10001L3L16L12L13L14jL15~_mplotcsv _x_y_pen_MLp_flags_Mseg L4"L5_Gerror _ML L66L7Z_Mputw _Mintsty L20001L20000L17cret mreset.ox \,w \ AWp CeAWpNBeq @t t@t7@tsfb ^ |d rAWt@l72 .*&  r55  @ & u- t& e5 & %  wreset - seg not open reset without a mark(8H(xxxxxx)_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mreset"~_mresetcsv _j_k_seg_addr_segptr_saveptr_Mseg L4L5\_Gerror _Msegs _Msave L6PL7q_Mblock L8z_Mfree _ML _Maddr _mflush _Mioptr _putw L9L20001L20003<cret mseg.o> x 8w N %  %     _ Wp Be |x` l ^& RWp Bet60WpNefWpN1 A^rJ7 _ 2 t5tf  &  UU   x jw \X J@ < .  & &  & @ & `  f @e7E 777z H   wVmseg -- seg no. out of range "%d"Setup not called yet!))))))8)HHHY88)))))))))i)))))))))))))y_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mseg"~_msegcsv _i_b_ai_segptr_addr_abs L4&L5_Gerror _Mioptr L6:L7L8VL10000HL10001L_msetup L3_Mseg L9|_Msegs _ML _mflush _Mhaddr _putw L10_Mfree _Mblock _Msave _Mgetfre _Mident _Maddr _Mintsty _Mputw cret mset.o'x @w DN 5 l x % %B7 %7i w E f`Wp CtBm FB 6f (& 77 80N~(Vxmset - scale factor out of range "%d"mset - text rotation out of range "%d"mset -- no open seg mset -- illegal option ignored "%s" )9iI_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mset"L10003L6(L20L9VL12xL14L17L18L19~_msetcsv _string_value_b_addr_op_option_n_Gsearch L100002L7PL8L20001<_Gerror L3tL10001DL11B_Mscale _Mrot L20004fL16icret L13_Mseg _Msegs _Mblock _mflush _Mioptr _putw _ML L21~mstring.ox w  Neffe2 %tWt@PU50De2  fe2 VpWp w`Wp %   N0  t̋  ̋E  % w&mstring -- no open seg or sub 8HYixY xxxxxx _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mstring"~_mstrincsv _format_args_rcp_word_count_string2_setstri0_Mseg L4L5_Gerror _Gsprint _Mscale _Mrot _Mputw _strlen _ML L8z_Msegs L9L10L11L3cret mvport.ożx 4|w | EEEE NU NU@ NU N U wwww wmvport -- no open seg or sub))))9_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mvport"~_mvportcsv _xl_yb_xr_yt _Mseg L4L5|_Gerror _Mputw _ML cret mxform.ox x<w N te & N w (9_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mxform"~_mxformcsv _seg_m_addr_b_Mseg_ok _Mblock _mflush _Mioptr _putw _Mmsend cret Mident.op x 0@w C  ww  w@@@@99_Midenti#0_ident"~_identcsv _m_f1_f2_j_Midenti L4L20001cret _Mident" ~_Mident _Mmsend Mmsend.o@ x Pw @e5D U  ta55%%e& & ff& @z  %w|   (Y(i_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Morder#_Mmsend"~_Mmsendcsv _m_rm_i_j_f_ipL20001_Mioptr _putw L7Rfaddzfisdtoi cret fltused fsubzfmulzfdivzac0 mcopy.ox  w DC  w _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mcopy"~_mcopycsv _m1_m2_rm1_rm2_nL4L20001cret mtrans.oux `w @fffffffff f fffe eNfef %ww N @p0p2@p4p6@p8p:wb))_mtrans"~_mtranscsv _m_sx_sy_sz_m1_Mtransm"^_mmult cret ~_Mtrans^_m_tx_ty_tz_ident fltused faddzfsubzfmulzfdivzac0 mrotate.o-vx 4w @fffffffff f fffe eNfef %ww vvz5 5 vvz5 5 ~xrvvz5 5 & & & & f f ff 5 5 @5 2f f ff e%f f ff e%& & & & ffff ^ 5 5 @5 2ffff 4e2,& %ffff e%& & & & ffff 5 5 @5 2ffff e%ffff lejd^X%& & ffffz@%& & ffffz@%& & ff @ %@0 0 & & ff ffz6 6 & & ffffz6 6 ffzz@%& & ffffz6 6 & & ffffz6 6 ffzz@%& & ffffz@%@0 0 & & ffffz6 6 ffz6 6 & & ffffzz@ "%& & ffffz6 6 ffz6 6 & & ffffzz@$&%& & ffffz@(*%@0 ,0 .@0 00 2@0 40 6@0 80 :@@<0 >w===))II_mrotate"~_mrotatcsv _m_ax_ay_az_m1_Mrotm"^_mmult cret L100004L10001<L10002D~_Mrotm^_m_ax_ay_az_sx_cx_sy_cy_sz_czfmulzfiscmpf L7"L8_sin ac0 _cos L9L10L11NL12fisnegf faddzfsubzfltused fdivzmscale.oux \w @fffffffff f fffe eNfef %ww N @Hp@pp@p(p*wd))_mscale"~_mscalecsv _m_sx_sy_sz_m1_Mscalem"^_mmult cret ~_Mscale^_m_sx_sy_sz_ident fltused faddzfsubzfmulzfdivzac0 msetup.o x H w   _ 7  %  7  % @ %2x pl b T$ F 8 * p  & e & Wp 1 % d @ e" te2t p %d V& J x8 * & L 7 7 7 ww N % Nf eWp C f2 e fL ewxw tpWp Ce %2te& Do dt77   63% f ww ?; !Wp efd r7`Wp efvWp ^,f7 b& %  w4/dev/mgr+wCannot open %s /dev/mg/dev/mgperr+wCannot open %s /dev/mgper%s -- Illegal seg "%d" %s -- Seg %d not defined %s -- Invalid operation on sub %d Out of free blocks !mflush --bad write count XhXXyyy()yHHIY( 9X(XX9(HXHiii9(i((i8X9_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Maddr _Mhaddr _Mioptr _Mpioptr _Mbuffer _Mfree _Mseg _Mrot _Mscale _Mintsty _Mpackfl _Meventv _Msegs _Msave  _Mblock @_Mrts _msetup"~_msetupcsv _j_ip_addr_vL4L3L6L5_fopen L7:L9L8_Gerror _setbuf L11L10L12nL14L13L20001t_mflush"<_putw L20003L20005n_Mpackfl _ML cret _Mseg_ok"~_Mseg_o_seg_routine_ai_b_abs L10000.L27FL28L29hL302L31L32L_Mputw"~_Mputw_x_b_segptrL36 _Mgetfre L37L38oL20009L39&~_mflush<_iop_base_nL43L45_write L48Mgetfree.oavx Zw Z t7tt7& %w out of free blocks! )_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Mgetfre"~_Mgetfrcsv _f_Mfree L4L5Z_Gerror _Mblock _Mrts _Mioptr _write cret mmult.oyx &f&f@Ae@e@wb& & && ff zz ~e<e*~B F%a(e_mmult"~mmultmnlabcbendfmulzfaddzfltused ac0 msub.ox "tw N %  % Wp Be !Wp Bet 7WpNefWpN1 A^rJ7 \ , R2 t6t7*d 7"777777wmsub -- sub no. out of range "%d"(99XiiiX99iiiiiii_GL _GW _Gfunc _Groutin _Glevel _Goutptr _msub"~_msubcsv _i_b_ai_subptr_addr_abs L10000L4(L5_Gerror _Mseg L6N_Msegs _ML L7_Mfree _Mblock _Msave L3_Mgetfre _Maddr cret mdata.o{x Hfl@AAAAA^megatek_GL _GW _Gfunc _Groutin _Glevel _Goutptr _MW#_ML#4L1^mend.oعx w  7 w_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mend"~_mendcsv _mflush _Mioptr _fclose cret mgvport.oQx ~w EEEE  fU fU@ fU f U w_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mgvport"~_mgvporcsv _xl_yb_xr_yt _b_mflush _Mioptr _putw cret mgvport.oQx ~w EEEE  fU fU@ fU f U wyy9)9iiiiiiiI_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mseg"~_msegcsv _i_b_ai_segptr_addr_abs L10000L4(L5_Gerror _Mseg L6N_Msegs _ML _Mflush _Mioptr _Mhaddr _putw L7_Mfree _Mblock _Msave L3_Mgetfre _Mident _Maddr _Mintsty cret mset.oQx @w DN 5 l x % %B7 %7i w E f`Wp CtBm FB 6f (& 77 80N~(Vxmset - scale factor out of range "%d"mset - text rotation out of range "%d"mset -- no open seg mset -- illegal option ignored "%s" )9iI_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mset"L10003L6(L20L9VL12xL14L17L18L19~_msetcsv _string_value_b_addr_op_option_n_Gsearch L100002L7PL8L20001<_Gerror L3tL10001DL11B_Mscale _Mrot L20004fL16icret L13_Mseg _Msegs _Mblock _Mflush _Mioptr _putw _ML L21~mstring.o9x w  Neffe2 %tWt@PU50De2  fe2 VpWp w`Wp %   N0  t̋  ̋E  % w&mstring -- no open seg or sub 8HYixY xxxxxx _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mstring"~_mstrincsv _format_args_rcp_word_count_string2_setstri0_Mseg L4L5_Gerror _Gsprint _Mscale _Mrot _Mputw _strlen _ML L8z_Msegs L9L10L11L3cret mvport.oZx hw EEEE NU NU@ NU N U wwww w_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mvport"~_mvportcsv _xl_yb_xr_yt _Mputw _ML cret mxform.oBx x<w N te & N w (9_GL _GW _Gfunc _Groutin _Glevel _Goutptr _mxform"~_mxformcsv _seg_m_addr_b_Mseg_ok _Mblock _Mflush _Mioptr _putw _Mmsend cret Mident.op x 0@w C  ww  w@@@@99_Midenti#0_ident"~_identcsv _m_f1_f2_j_Midenti L4L20001cret _Mident" ~_Mident _Mmsend Mmsend.o@ x Pw @e5D U  ta55%%e& & ff& @z  %w|   (Y(i_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Morder#_Mmsend"~_Mmsendcsv _m_rm_i_j_f_ipL20001_Mioptr _putw L7Rfaddzfisdtoi cret fltused fsubzfmulzfdivzac0 mcopy.ox  w DC  w _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mcopy"~_mcopycsv _m1_m2_rm1_rm2_nL4L20001cret mtrans.oux `w @fffffffff f fffe eNfef %ww N @p0p2@p4p6@p8p:wb))_mtrans"~_mtranscsv _m_sx_sy_sz_m1_Mtransm"^_mmult cret ~_Mtrans^_m_tx_ty_tz_ident fltused faddzfsubzfmulzfdivzac0 mrotate.o-vx 4w @fffffffff f fffe eNfef %ww vvz5 5 vvz5 5 ~xrvvz5 5 & & & & f f ff 5 5 @5 2f f ff e%f f ff e%& & & & ffff ^ 5 5 @5 2ffff 4e2,& %ffff e%& & & & ffff 5 5 @5 2ffff e%ffff lejd^X%& & ffffz@%& & ffffz@%& & ff @ %@0 0 & & ff ffz6 6 & & ffffz6 6 ffzz@%& & ffffz6 6 & & ffffz6 6 ffzz@%& & ffffz@%@0 0 & & ffffz6 6 ffz6 6 & & ffffzz@ "%& & ffffz6 6 ffz6 6 & & ffffzz@$&%& & ffffz@(*%@0 ,0 .@0 00 2@0 40 6@0 80 :@@<0 >w===))II_mrotate"~_mrotatcsv _m_ax_ay_az_m1_Mrotm"^_mmult cret L100004L10001<L10002D~_Mrotm^_m_ax_ay_az_sx_cx_sy_cy_sz_czfmulzfiscmpf L7"L8_sin ac0 _cos L9L10L11NL12fisnegf faddzfsubzfltused fdivzmscale.oux \w @fffffffff f fffe eNfef %ww N @Hp@pp@p(p*wd))_mscale"~_mscalecsv _m_sx_sy_sz_m1_Mscalem"^_mmult cret ~_Mscale^_m_sx_sy_sz_ident fltused faddzfsubzfmulzfdivzac0 msetup.oQx w  7  %   7 + % @ %2 |x n `$ R D 6 (p   & e & Wp 1 % d @ e" te2t p %p b& V D 6 (& t7 7 7 67 7777ww N % Nf> eWp C N&V e N&p ew\w XTWp Ce %2te& ( dt77   63% f ww ?; !Wp efd r7`lhWp efZWp ^,J7 F& %  w/dev/mgr+wCannot open %s /dev/mg/dev/mgperr+wCannot open %s /dev/mgperMegatekIllegal seg "%d" -- %s Seg %d not defined -- %s Invalid operation on sub %d -- %s Out of free blocks !Mflush --bad write count HXHhyyy()yHHI IYX YYYYYY)H(HH)(HyHHi ii ) (i((i (H)_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Maddr _Mhaddr _Mioptr _Mpioptr _Mbuffer _Mfree _Mseg _Mrot _Mscale _Mintsty _Mpackfl _Meventv _Msegs _Msave  _Mblock @_ML *_Mrts _msetup"~_msetupcsv _j_ip_addr_vL5L4_fopen L6.L8L7_Gerror _setbuf L10L9 L11bL13+L12L20001h_Mflush"X_putw L20003L20005b_Mpackfl L236cret _Mseg_ok"4~_Mseg_o4_seg_routine_ai_b_abs L10000JL27bL28>L29L30VL31L32p_Mputw"~_Mputw_x_b_segptrL36(_Mgetfre L37L38L200094L39B~_MflushX_iop_base_nL43L45_write L48Mgetfree.oavx Zw Z t7tt7& %w out of free blocks! )_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Mgetfre"~_Mgetfrcsv _f_Mfree L4L5Z_Gerror _Mblock _Mrts _Mioptr _write cret mmult.oyx &f&f@Ae@e@wb& & && ff zz ~e<e*~B F%a(e_mmult"~mmultmnlabcbendfmulzfaddzfltused ac0 msub.o^x "tw N %  % Wp Be Wp Bet 7WpTefWpT1 A^rJ7 d , Z2 t>t72d 7*7$77777wmsub -- sub no. out of range "%d"(99XiiiX99iiiiiii_GL _GW _Gfunc _Groutin _Glevel _Goutptr _msub"~_msubcsv _i_b_ai_subptr_addr_abs L10000L4(L5_Gerror _Mseg L6N_Msegs _ML L7_Mfree _Mblock _Msave L3_Mgetfre _Maddr cret 99iiiiiii_GL _GW _Gfunc _Groutin _Glevel _Goutptr _msub"~_msubcsv _i_b_ai_subptr_addr_abs L10000L4(L5_Gerror _Mseg L6N_Msegs _ML L7_M0@w C  ww  w@@@@99_Midenti#0_ident"~_identcsv _m_f1_f2_j_Midenti L4L20001cret _Mident" ~_Mident _Mmsend Mmsend.o@ x Pw @e5D U  ta55%%e& & ff& @z  %w|   (Y(i_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Morder#_Mmsend"~_Mmsendcsv _m_rm_i_j_f_ipL20001_Mioptr _putw L7Rfaddzfisdtoi cret fltused fsubzfmulzfdivzac0 mcopy.ox  w DC  w _GL _GW _Gfunc _Groutin _Glevel _Goutptr _mcopy"~_mcopycsv _m1_m2_rm1_rm2_nL4L20001cret mtrans.oux `w @fffffffff f fffe eNfef %ww N @p0p2@p4p6@p8p:wb))_mtrans"~_mtranscsv _m_sx_sy_sz_m1_Mtransm"^_mmult cret ~_Mtrans^_m_tx_ty_tz_ident fltused faddzfsubzfmulzfdivzac0 mrotate.o-vx 4w @fffffffff f fffe eNfef %ww vvz5 5 vvz5 5 ~xrvvz5 5 & & & & f f ff 5 5 @5 2f f ff e%f f ff e%& & & & ffff ^ 5 5 @5 2ffff 4e2,& %ffff e%& & & & ffff 5 5 @5 2ffff e%ffff lejd^X%& & ffffz@%& & ffffz@%& & ff @ %@0 0 & & ff ffz6 6 & & ffffz6 6 ffzz@%& & ffffz6 6 & & ffffz6 6 ffzz@%& & ffffz@%@0 0 & & ffffz6 6 ffz6 6 & & ffffzz@ "%& & ffffz6 6 ffz6 6 & & ffffzz@$&%& & ffffz@(*%@0 ,0 .@0 00 2@0 40 6@0 80 :@@<0 >w===))II_mrotate"~_mrotatcsv _m_ax_ay_az_m1_Mrotm"^_mmult cret L100004L10001<L10002D~_Mrotm^_m_ax_ay_az_sx_cx_sy_cy_sz_czfmulzfiscmpf L7"L8_sin ac0 _cos L9L10L11NL12fisnegf faddzfsubzfltused fdivzmscale.oux \w @fffffffff f fffe eNfef %ww N @Hp@pp@p(p*wd))_mscale"~_mscalecsv _m_sx_sy_sz_m1_Mscalem"^_mmult cret ~_Mscale^_m_sx_sy_sz_ident fltused faddzfsubzfmulzfdivzac0 msetup.oQx w  7  %   7 + % @ %2 |x n `$ R D 6 (p   & e & Wp 1 % d @ e" te2t p %p b& V D 6 (& t7 7 7 67 7777ww N % Nf> eWp C N&V e N&p ew\w XTWp Ce %2te& ( dt77   63% f ww ?; !Wp efd r7`lhWp efZWp ^,J7 F& %  w/dev/mgr+wCannot open %s /dev/mg/dev/mgperr+wCannot open %s /dev/mgperMegatekIllegal seg "%d" -- %s Seg %d not defined -- %s Invalid operation on sub %d -- %s Out of free blocks !Mflush --bad write count HXHhyyy()yHHI IYX YYYYYY)H(HH)(HyHHi ii ) (i((i (H)_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Maddr _Mhaddr _Mioptr _Mpioptr _Mbuffer _Mfree _Mseg _Mrot _Mscale _Mintsty _Mpackfl _Meventv _Msegs _Msave  _Mblock @_ML *_Mrts _msetup"~_msetupcsv _j_ip_addr_vL5L4_fopen L6.L8L7_Gerror _setbuf L10L9 L11bL13+L12L20001h_Mflush"X_putw L20003L20005b_Mpackfl L236cret _Mseg_ok"4~_Mseg_o4_seg_routine_ai_b_abs L10000JL27bL28>L29L30VL31L32p_Mputw"~_Mputw_x_b_segptrL36(_Mgetfre L37L38L200094L39B~_MflushX_iop_base_nL43L45_write L48Mgetfree.oavx Zw Z t7tt7& %w out of free blocks! )_GL _GW _Gfunc _Groutin _Glevel _Goutptr _Mgetfre"~_Mgetfrcsv _f_Mfree L4L5Z_Gerror _Mblock _Mrts _Mioptr _write cret mmult.oyx &f&f@Ae@e@wb& & && ff zz ~e<e*~B F%a(e_mmult"~mmultmnlabcbendfmulzfaddzfltused ac0 msub.o^x "tw N %  % Wp Be Wp Bet 7WpTefWpT1 A^rJ7 d , Z2 t>t72d 7*7$77777wmsub -- sub no. out of range "%d"(99XiiiX99iiiiiii_GL _GW _Gfunc _Groutin _Glevel _Goutptr _msub"~_msubcsv _i_b_ai_subptr_addr_abs L10000L4(L5_Gerror _Mseg L6N_Msegs _ML L7_Mfree _Mblock _Msave L3_Mgetfre _Maddr cret 99iiiiiii_GL _GW _Gfunc _Groutin _Glevel _Goutptr _msub"~_msubcsv _i_b_ai_subptr_addr_abs L10000L4(L5_Gerror _Mseg L6N_Msegs _ML L7_M6 6 z6 6 ffz6 6 ^XzzffffPNLJw L& z6 6  X  6  L5 6 e]& z6 6 vEWtf6EUv   v6dz e e e 0 e  UUU   &6xTflBNo seg open -- mplotInvalid pen code "%d"mseg -- seg no. out of range "%d"@@@@   /dev/mgr+wCannot open %s /dev/mg/dev/mgperr+wCannot open %s /dev/mgperMegatekIllegal seg "%d" -- %s Seg %d not defined -- %s Out of free blocks !Mflush --bad write count out of free blocks!  %s error doxfexcslLurDOX U(null)arwd~P=P=(& ?@OLX2xIX]DLIfNGbDKrMegatekIllegal seg "%d" -- %s Seg %d not defined -- %s Out of free blocks !Mflush --bad write count out of free blocks!  %s error doxfexcslLurDOX U(null)arwd~P=P=0 & 6  8w _ L Ne Ŷ5 & & & & & & ff& & fffe he& & & A& & & A& & & Afe e 7WpwŶ5 %v7l r7a\Z\RTLJ %&&  e &&  e &&  e  &&  e  &&  e &&  e &&  e&&  e Ne F wpD_ w X@A 1`6@ A 1`6@> %w0w DC B Z Vff& e ff e &ff& e  &ff e ff& eff eff& ewhw VDC   l ( a`EE5 @ # xnt 5U` N] @ N U UN  %UU @]UP ww  N P%   % Wp Be 42` $ & Wp Bet,!WpTej'fWpT1 l'Al'^rJ7  _B 2 t5*!t,!f  t& h ZUU L > 0 "w  @  H     & &  z& n@ `& PN` @ 2f f@e7.,;z 7N7H7B7B7<7:74ww N t*!e J& N  2ww C  ww  ww r@e5D VU  ta55%%e& & ff& @z J %ww @fffffffff f fffe eNfef x %ww N @Hp@pp@p(p*wbw R@fffffffff f fffe eNfef x %ww N @p0p2@p4p6@p8p:ww 4, 7 H8  %B2~ [P 7) o_  %3 @ %2: 0. " $    p  & e & Wp  % _v h@ Xe" t*!e2t p,! %j" &    & Z7 7 ((7 (lz 7 7777ww ~N P% Nf  eWp C N&  ew8w (fWp Ce %2te,!&   _t7*!&7 ' & 63%& f d'ww tl.* F'Wp ef_ r7`R&7 '& %   ww   t7,!t,!t7*!&3& %w&f&f@Ae@e@wF+& & && ff zz ~e<e+~B F%a(ew (   ff %ww D% P!te& %tfef %t&   %%  v 8 w w DC  ; &  t; t&  wN w < D   t 4 w 7) )7)7)7)7)  ӕ-ӕ0 C~z) ӕ. ӕ0 ~ nC~7Z) P)7x)7v)7t)7r) ӕ- <ӕ.()  ,C~ӕe ӕ- ӕ+ r e0e0S 0fw)w)w(w (w ( 8fw(w(w(w (w ( }(7 z(&& ((((!EU (  "   8 7 &tEe0E!87m' 'c 8 7eȐ9 ȕ0 7ȕ1 ' 'c 8 707 ' 7    w' r &@'r&@r(@rP r  vA `B A @ &&f  eB A @ eA @ e@ e B A @    w " uDAB %u f& & e w 5 5  W- W00u5  .xu Bw6 J@  o x d u        ӕ- f&@Ew ӕ0 S r@A r  f  e0 9e' E,* ALҋ D~@B v@  5w:A  fff <e w 5  @ 0   Wp `e0w DCB Y +̥-%0  E: &E  z f    E: &E    z f  w2w D_uNfe& %4 ?'%l  r 33 p  & %S  @wDw .D&E%& %   ww  d-  peww D.@     4 4 w^w LD_  _@+ @;f  ; f l  %f  &  e  f l   $T7 y  4  Հ rwjw XD&      & l w*w d- ewf @f  E:PPPPw  8U7 8U7 8 8 Ae vBl 7 n 55 a  a!RE -4 %8 w: & % e rt 7   `e   %e U? `e 78U? a7 ?U ew zDbE wlw \D5 @ r5N p!w*5A vBB-  }ee@ !ۃ `!ւ `@ r `w Nef   wf@w`wh f@wR fw4w0 w2w 8  %   N ff %% @tAWtE@PN e&f % wfEfwwwfwm~wtpwmjfwZwRwL f@w<w8w( f@ww"w7F@& BF L& z6 6  X  6  L5 6 e]& z6 6 ^ZvEWtf6EUv   v6z e e e  e UUU  &6xdv|$RNo seg open -- mplotInvalid pen code "%d"mseg -- seg no. out of range "%d"@@@@   /dev/mgr+wCannot open %s /dev/mg/dev/mgperr+wCannot open %s /dev/mgperMegatekIllegal seg "%d" -- %s Seg %d not defined -- %s Out of free blocks !Mflush --bad write count out of free blocks!  %s error doxfetcslLurDOXU(null)arw` z55 *8crt0.ostartsierp.o~_main_h_i_m_offset~_line_d1_d2_h1_h2 ~_curve_j_d1_d2_h1_h2faddzfsubzfmulzfdivzmplot.o~_mplot_x_y_pen_MLp_flags_intsmseg.o~_mseg_i_b_ai_segptr_addrmxform.oF~_mxformF_seg_m_addr_bMident.o~_ident_m_f1_f2_j~_MidentMmsend.o~_Mmsend_m_rm_i_j_f_ipfaddzfsubzfmulzfdivzscaleit.6~_scalei6_m_sx_sy_sz_m1faddzfsubzfmulzfdivzscalem.o~_scalem_m_sx_sy_szfaddzfsubzfmulzfdivztransit.~_transi_m_sx_sy_sz_m1faddzfsubzfmulzfdivztransm.o0~_transm0_m_tx_ty_tzfaddzfsubzfmulzfdivzmsetup.op~_msetupp_j_ip_addr_v~_Mseg_o _seg_routine_ai_b~_Mputw _x_b_segptr~_Mflush _iop_base_nMgetfree ~_Mgetfr _fmmult.ox ~mmultx mnlabcbend7fmulzfaddzfopen.o ~_fopen _file_modeGerror.o ~_Gerror _errmsg_errtype_args_errputw.o ~_putw _i_iopsetbuf.o ~_setbuf _iop_buffltpr.o,_ndigit7ac08fcvtdmovedigecvt^eflag7scalednormVmul10div10trightbuf7buftop8done$leftsavedr18doprnt.owidthformprjustndfndndigitzfillloopgnum swtab prbufdecimaloctalhexfloatsciencharactstringlongorununsignedremotelongloctlhexlunsignecomputenulstrLprstrstrout.o>~__strou>_string_count_adjust_file_fillch flsbuf.o~__flsbu_c_iop_base_n_rn_c1~_fflush_iop_base_n~__cleanN_iop~_fclosep_iop_rendopen.~__endop_file_mode_iop_rw_f_create~_create_file_rw_ffindiop. ~__findi _iopdata.o8cuexit.o8abort.oFiotabs.oPmalloc.op_allocs8_allocp8_alloct 8_allocx"8~mallocpnbytespqnwtemp$8~freeapp~reallocpnbytesqstnwonwisatty.or~_isattyr_f_ttybgtty.oclose.ocreat.olseek.o~lseekfp ro0o1open.olsbrk.ondseek.owrite.ocerror.ocsv.o(fis.oBfsubzreturn(8savr5$7_exit"8_main"_GL$(_GW$*_Gfunc$,_Groutin$._Glevel#_Goutptr$0_pos0$2_pos$6csv"(_msetup"p_mseg"_ident"_transit"_scaleit"6_mplot"_curve"_line"_mxform"Fcret"4fltused",ac0$:_Mseg$j_Gerror" _ML$l_Mintsty$_Mputw" _abs"P_Msegs$_Mflush" _Mioptr$$!_Mhaddr$&!_putw" _Mfree$(!_Mblock$*!_Msave$j'_Mgetfre" _Mident"_Maddr$>2_Mseg_ok" _Mmsend"_Midenti#_Morder#fisdtoi"j_scalem"_mmult"x _transm"0_Mpioptr$@2_Mbuffer$B2_Mrot$ 3_Mscale$3_Mpackfl$3_Mrts$3_fopen" _setbuf" _write"__findio" __endope"__iob#d__doprnt"_fflush"_abort"F__flsbuf"_free"pfloat",pscien"_ecvt"_fcvt"(__strout">_isatty"r__sobuf$3_malloc"p__cleanu"N__lastbu#_fclose"p_close"_open"l_errno$5_lseek"_creat"__sibuf$5_fabs"Z_sbrk"_realloc"_gtty"cerror"_seek"_end$*8_brk"fisitod"Bfisdtol"fisltod"xfiscmpf"fiststf"Dfisnegf"ns$3_fopen" _setbuf" _write"__findio" __endope"__iob#d__doprnt"_fflush"_abort"F__flsbuf"_free"pfloat",#include /* * draw sierpinski curves on the megatek */ #define n 5 /* order of the curve */ #define h0 2048 /* resolution */ #define X 1 #define Y 0 int pos0[2],pos[2]; main() { register int h , i; float m[4][4]; float offset; msetup(); mseg(1); ident(m); offset = -h0/2; transit(m,offset,offset,0.); scaleit(m,2.0,2.0,2.0); h = h0/4; pos0[X]=2*h; pos0[Y] = 3*h; offset = -h0/2; for(i=1;i<=n;i++){ pos0[X] -= h; h = h/2; pos0[Y] += h; pos[X] = pos0[X]; pos[Y] = pos0[Y]; mplot(pos[X],pos[Y],3); curve(i,X,Y,h,h); line(X,Y,h,-h); curve(i,Y,X,-h,h); line(X,Y,-h,-h); curve(i,X,Y,-h,-h); line(X,Y,-h,h); curve(i,Y,X,h,-h); line(X,Y,h,h); } mxform(1,m); /* sleep(3); for(;;){ rotit(m,0.,0.,30.); scaleit(m,0.95,0.95,0.95); mxform(1,m); } */ } line(d1,d2,h1,h2) { pos[d1] += h1; pos[d2] += h2; mplot(pos[X],pos[Y],2); } curve(j,d1,d2,h1,h2) register int j , h1 , h2; { if(j>0){ curve(j-1,d1,d2,h1,h2); line(d1,d2,h1,-h2); curve(j-1,d2,d1,-h2,h1); /* rotate -pi/2 */ line(d1,d2,2*h1,0); curve(j-1,d2,d1,h2,-h1); /* rotate +pi/2 */ line(d1,d2,h1,h2); curve(j-1,d1,d2,h1,h2); } } -h,h); curve(i,Y,X,h,-h); line(X,Y,h,h); } mxform(1,m); /* sleep(3); for(;;){ rotit(m,0.,0.,30.); scaleit(m,0.95,0.95,0.95); mxform(1,m); } */ } line(d1,d2,h1,h2) { pos[d1] += h1; pos[d2] += h2; mplot(pos[X],pos[Y],2); } curve(j,d1,d2,h1,h2) register int j , h1 , h2; { if(j>0){ curve(j-1,d1,d2,h1,h2); line(d1,d2,h1,-h2); curve(j-1,d2,d1,-h2,h1); /w _  Ne Ŷ5 & & & & & & ff& & fffe e& & & A& & & A& & & Afe e 7tWpwhŶ5 %v7R r7aB@>86., %&&  e &&  e &&  e  &&  e  &&  e &&  e &&  e&&  e Ne wTD_w H@A 1`@ A 1`" %ww DC B Z Vff& e ff e &ff& e  &ff e ff& eff eff& ewL(8IYiiiiiyiyyyxxyy_GL _GW _Gfunc _Groutin _Glevel _Goutptr _pos0 _pos _main"~_maincsv L1L2_h_i_m_offset_msetup _mseg _ident _transit _scaleit L4L5_mplot _curve"_line"L6_mxform L3cret ~_line_d1_d2_h1_h2 L7L8L9~_curve_j_d1_d2_h1_h2L10L11L13L12fltused faddzfsubzfmulzfdivzac0 _h_i_m_offset_msetup _mseg _ident _transit _scaleit L4L5_mplot _curve"_line"L6_mxform L3cret ~_line_d1_d2_h1_h2 L7L8L9~_curve_j_d1_d2_h1_h2L10L11L13L12fltused faddzfsubzfmulzfdivf & 6  w d  F00 z%0 z% z%0 z%00 z% F & & z%&  z% z%& z%& & z%w2w  ff  N 4 Wp Be.n J a rWt@l7tt&br J e"" "ww DC  # ( a`EE5 @ # x|R"t 5U` 2N] 2@ 2N U 2UN %UU 2@]UP 2ww  N 4%  % Wp Be.v!r!n! L!!` | |! | n!& | Wp Be.tJ!D!WpTe.$fWpT1 0$A0$^rJ7  _ 82 t5t f |   |  & |   |  UU |   |   |   | z w | Vh  | Z @ | L  | > H | 0  | "  |   |   | & | & |  | & | @ | & | h` |  | f | 8|@e7=^ 727,7&7&7 77w&w C  ww  "ww @e5D U |  ta55%%e& & ff& @z  | %wrw b.& 7h B2 %4/L UJ 7>) iY %0 @ %2  |  | $ |  |  |  | p |  | & | ex | j& | Wp . % aRD | 6@ | &e" te2t p % | & |  |  |  | & | X7 7 b(^(7 \(Jzz#ltf7 d7D7>7<76w<w ,N 4% Nf| eWp C. N& eww Wp Ce.  2te&  at707 r' |  | 63p%d | Vf | 'w4w $</%* '&Wp e2fa r7`7 && %  ww  t7tt7r&0& %wjw Z  8 ff %wJw 8D% 4!n0e& %nfef %n&  %%    w w ffef %  w w DC  ; &  t; t&  wN w < D   t 4 w 7) )7)7)7)7)  ӕ-ӕ0 C~) ӕ. ӕ0 ~ nC~7d) Z)7)7)7~)7|) ӕ- <ӕ.2)  ,C~ӕe ӕ- ӕ+ r e0e0S 0fw)w )w)w )w ( 8fw(w(w(w (w ( }(7 (&& ((((!EU (  "   8 4 &tEe0E!44m( 'c 4 4eȐ9 ȕ0 4ȕ1 ' 'c 4 404 ' 4    w' r &@'r&@r(@rP r  vA `B A @ &&f  eB A @ eA @ e@ e B A @    w " uDAB %u f& & e w 5 5  W- W00u5  .xuBw6 J@  o x d u        ӕ- f&@Ew ӕ0 S r@A r  f  e0 9e' E,* AFҋ D~@B v@  5w:A  fff <e w 5  @ 0   Wp `e0w DCB Y +̥-%0  E: &E  z f    E: &E    z f  w2w D_uNfe& %4 ?'%f#  V 00 T  & %S  @wDw .D&E%& %   ww  ^-  Teww D.@     4 4 w^w LD_  _@+ @;f  ; f P  %f  &  e  f P   $N7 y  4  Հ rwjw XD&      & P w*w ^- ewf @f  E/PPPPw   5U7 5U7  5 5 Ae vBv 7 x 55 a  a!RE -> %5 w: 0 %* e rt 7  n `e   n%e U? `e 75U? a7 ?U ew zDlE wlw \D5 @ r5N T!w*5A vBB-  }ee@ !ۃ `!ւ `@ r `w Nef ~  wf@wvwh f@wR fwJwFw2w 8  %   N ff %% @tAWtE@PN e&f % wfEfww wfwmwtwmfwpwRwb f@wRwNw( f@w4w0w7F@& BF L& z6 6  X  6  L5 6 e]& z6 6 hdvEWtf6EUv   v6z e e e  e UUU  &6xmappend%o %o %o %o B"(No seg open -- mplotInvalid pen code "%d"mseg -- seg no. out of range "%d"@@@@   /dev/mgr+wCannot open %s /dev/mg/dev/mgperr+wCannot open %s /dev/mgperMegatekIllegal seg "%d" -- %s Seg %d not defined -- %s Out of free blocks !Mflush --bad write count out of free blocks!  %s error doxfeXcjslLurDOXU(null)arwD^22 5crt0.ostartt.o~_main_i_jmappend.~_mappen_i_b_ai_segptrmplot.oz~_mplotz_x_y_pen_MLp_flags_intsmseg.oF~_msegF_i_b_ai_segptr_addrMident.o~_ident_m_f1_f2_j~_MidentMmsend.o"~_Mmsend"_m_rm_i_j_f_ipfaddzfsubzfmulzfdivzmsetup.o~_msetup_j_ip_addr_v~_Mseg_o_seg_routine_ai_b~_Mputw2_x_b_segptr~_Mflush_iop_base_nMgetfreeT ~_MgetfrT _ffopen.o ~_fopen _file_modeGerror.o ~_Gerror _errmsg_errtype_args_errprintf.oJ ~_printfJ _fmt_argsputw.o| ~_putw| _i_iopsetbuf.o ~_setbuf _iop_buffltpr.o _ndigit4ac04fcvtH movedig ecvtB eflag4scaled norm: mul10 div10X right buf4buftop4done left savedr15doprnt.o widthformprjustndfndndigitzfillloop gnumswtabprbufdecimaloctalhexfloatsciencharacXstringjlongorununsignedremotelongloctlhexlunsignecomputenulstrFprstrstrout.o"~__strou"_string_count_adjust_file_fillch flsbuf.o~__flsbu_c_iop_base_n_rn_c1~_fflush_iop_base_n~__clean2_iop~_fcloseT_iop_rendopen.~__endop_file_mode_iop_rw_f_create~_create_file_rw_ffindiop.~__findi_iopdata.ocuexit.oabort.o*iotabs.o4malloc.oT_allocs5_allocp 5_alloct5_allocx5~mallocTnbytespqnwtemp5~freeapp~reallocpnbytesqstnwonwisatty.oV~_isattyV_f_ttybgtty.o~close.ocreat.olseek.o~lseekfp ro0o1open.oPsbrk.onndseek.owrite.ocerror.ocsv.o fis.o&fsubzreturn5savr5$4_exit"_main"csv" _msetup"_mseg"F_mplot"z_mappend"cret"_GL$"_GW$$_Gfunc$&_Groutin$(_Glevel#_Goutptr$*_Mflush"_Mseg_ok"_abs"4_Mseg$,_Msegs$._Maddr$_printf"J _Mblock$_ML$#_Gerror" _Mintsty$&$_Mputw"2_Mioptr$($_Mhaddr$*$_putw"| _Mfree$,$_Msave$.$_Mgetfre"T _Mident"_Midenti#_ident"_Mmsend""_Morder#fisdtoi"Nfltused" ac0$/_Mpioptr$2/_Mbuffer$4/_Mrot$/_Mscale$/_Mpackfl$0_Mrts$0_fopen" _setbuf" _write"__findio"__endope"__iob#^__doprnt" _fflush"_abort"*__flsbuf"_free"pfloat" pscien"j _ecvt" _fcvt" __strout""_isatty"V__sobuf$0_malloc"T__cleanu"2__lastbu#_fclose"T_close"_open"P_errno$2_lseek"_creat"__sibuf$2_fabs">_sbrk"n_realloc"_gtty"~cerror"_seek"_end$5_brk"fisitod"&fisdtol"fisltod"\fiscmpf"fiststf"(fisnegf"Rs$0_fopen" _setbuf" _write"__findio"__endope"__iob#^__doprnt" _fflush"_abort"*__flsbuf"_free"pfloat" pscien"j _ecvt" _fcvt" __strout""_isatty"V__sobuf$0_malloc"T__cleanu"2__lastbu#_fclose"T_closemain() { register int i,j; msetup(); mseg(1); mplot(-2000,-2000,3); mplot(2000,-2000,2); mplot(2000,2000,2); mplot(-2000,2000,2); mplot(-2000,-2000,2); mseg(2); mappend(1); mplot(0,0,3); mplot(1000,0,2); mplot(1000,1000,2); mplot(0,1000,2); mplot(0,0,2); } "__findio"__endope"__iob#^__doprnt" _fflush"_abort"*__flsbuf"_free"pfloat" pscien"j _ecvt" _fcvt" __strout""_isatty"V__sobuf$0_malloc"T__cleanu"2__lastbu#_fclose"T_close mseg( iseg ) Purpose: Initialize or destroy a megatek segment. Argument: iseg ... the segment number. Notes: If iseg is positive, the seg is initialized and opened. If iseg is negative, the seg is destroyed. side effects. e definition of the pattern. vectors. ; cx=cos(ax); } if (ay == 0.0 ) { sy=0.0; cy=1.0; } else { sy=sin(ay); cy=cos(ay); } if (az == 0.0 ) { sz=0.0; cz=1.0; } else { sz=sin(az); cz=cos(az); } m[0][0]= cy*cz; m[0][1]= cy*sz; m[0][2]= -sy; m[0][3]= 0.; m[1][0]= -c mstring(iscl , str [, rot] ) Purpose: Plot a string at the current beam position. Arguments: iscl ... the Megatek scale factor. str ... the string. rot ... (optional) - the quadrant rotation at which the characters will be plotted. Notes: The scale factor is in the range 0-7. The quadrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quotes in C, this is automatically taken care of). ring at the current beam position. Arguments: iscl ... the Megatek scale factor. str ... the string. rot ... (optional) - the quadrant rotation at which the characters will be plotted. Notes: The scale factor is in the range 0-7. The quadrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quote new_matrix(iseg , m) Purpose: Replace a segment's header transformation with a new one. Arguments: iseg ... the segment number. m ... a 4x4 floating point matrix. ional) - the quadrant rotation at which the characters will be plotted. Notes: The scale factor is in the range 0-7. The quadrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quoteK-+$$+-+$$+e;e8e0#e#0e8e;e8e0e#eeeeeeeee#e0e8=:1$$1:=:1$$1:=:1$$1:=:1$$1:{={:{1${$1{:{={:{1{${{{{{{{{{${1{:-=-:-1$-$1-:-=-:-1-$---------$-1-:=:1$$1:=:1$$1:=:1$$1:=:1$$1:C=C:C1$C$1C:C=C:C1C$CCCCCCCCC$C1C:=:1$$1:=:1$$1:=:1$$1:=:1$$1:Y<Y9Y1#Y#1Y9Y<Y9Y1Y#YYYYYYYYY#Y1Y9 9 7 ." ". 7 9 7 . "   " . 741**141**1o.o,o%o%o,o.o,o%ooooooooooo%o,!)!' !"!"! '!)!'!"!! !!!!!!! !!"!'%#  #%# #     77777777777777777777oWq7qplATT/;p;)33 dd*o*W7pA/p) {TTT{:TV:VTVVXXXX            ! ! ""!##"$$#%%$&&%''&((')))(*++*,,+--,..-//.00/1102213324 435!546"657#768$879%98:&:9;';:<(<;=)=*=<>*?+?>@,@?A-A@B.BAC/CBD0DCE1EDF2FEG3GFH4HGI5IHJ6JIK7KJL8LKM9MLN:NMO;ONP<POQ=Q>QPR>S?SRT@TSUAUTVBVUWCWVXDXWYEYXZFZY[G[Z\H\[]I]\^J^]_K_^`L`_aMa`bNbacOcbdPdceQeRedfRgSgfhThgiUihjVjikWkjlXlkmYmlnZnmo[onp\poq]qpr^rqs_srt`tsuautvbvuwcwvxdxwyeyfyxzf{g{z|h|{}i}|~j~}k~lmnopqrstuvwxyzz{|}~                     ! ! ""!##"$$#%%$&&%''&(('))(**)++*,,+---,.//.00/1102213324 435!546"657#768$879%98:&:9;';:<(<;=)=<>*>=?+?>@,@?A-A.A@B.C/CBD0DCE1EDF2FEG3GFH4HGI5IHJ6JIK7KJL8LKM9MLN:NMO;ONP<POQ=QPR>RQS?SRT@TSUAUBUTVBWCWVXDXWYEYXZFZY[G[Z\H\[]I]\^J^]_K_^`L`_aMa`bNbacOcbdPdceQedfRfegSgfhThgiUiVihjVkWkjlXlkmYmlnZnmo[onp\poq]qpr^rqs_srt`tsuautvbvuwcwvxdxwyeyxzfzy{g{z|h|{}i}j}|~j~k~~~l~m~n~o~p~q~r~s~t~u~v~w~x~y~z~{~|~}hThgiUiVihjVkWkjlXlkmYmlnZnmo[onp\poq]qpr^rqs_srt`tsuautvbvuwcwvxdxwyeyxzfzy{g{z|h|{}i}j}|~x4 0000000 0000000000000$0)0,0,0+ 0%000 0 &,047. #   (.288+ EC>7*)4*-7 >CE+N+K+E+<+/++ +++++++++ ++#+++2+7+8+8+) +.+:/+0<+#E+K+NLJE;/ "*27886<:/0;#EJLuIuGuBu8u+uuuuuuuuuuu uuu'u1u:u:u8u<u:u5+u-8u!BuGuIED?5( (2888851(+5 ?DE<><=<8<0<%<<<<<<<<<<< <<<'> >!>=?"?>@#@$@?A%A&A'A@B(BAC)CBD*DCE*EDF+FEG,GFH-HGI.IHJ/JIK/KJL0LKM1ML2MN2NNO2ONO3OOP4POQ5QPR6RQS7SRT8TSU9UTV:VUW;WVX<XWY=YXZ>ZY[?[@[Z\A\[]B]\^C^]_D_^`E`_aFa`bGbacHcbdIdceJedfKfefLffgMgfNghNiOihjPjQjikRkjlRlSlkmTmlRURmSUTVXXYYZZ_]`^a_b_c`n`ncoaobonpcpoqcqdqprerfrqsfsgshsrthtsuiutvjvuwkwvxlxwymyxzRzy{S{T{z|U|{}V}|~V~}W~XYZZ[\]^__`abcnopqrttuvwxyz{|}~                !! ""!##"$$#%%$   %& ' '&( (') )(* *)+ +*,,,+--,..-//.00/110221332443554665776887998::9;;:<<;== =<>!>=?"?>@#@?A$A@B%BA&&&BC&D&DCE'EDF(FEG)GFH*HGI+IHJ,JIK-KJL.LKM/MLN0NMO1ONP2POQ3QPR4R5RQS6SRT7TSU8UTV9VUW:WVX;XWY<YXZ=ZY[>[Z\?\[]@]\^A^]_B_^CCC_`C`D`E`F`G`H`I`J`K`L`M`N`O`P`Q`R`S`T`U`V`W`X`Y`Z`[`\`]`^`_bacadbdcecfdfegehfhgjikiljlkmknlnmompnporqsqtrtsvuwuxvxw>=?"?>@#@?A$A@B%BA&&&BC&D&DCE'EDF(FEG)GFH*H# #include "megatek.h" /* * wait for any peripheral to be struck and return its word: */ wait_event() { register int v0; int v[3]; #include "externs.h" v[2] = 0; v[0] = WAIT; stty(FDMEGP , v); gtty(FDMEGP , v); v0 = v[0]; v[0] = v[2] = 0; stty(FDMEGP , v); return(v0); } 0177000); /* move to 0,0,0 */ min_buf(0010000); min_buf(0140000); min_buf(0040000); mrts(); /* first word in DL is a return! */ mflush_buf(); block[b].nleft = BLOCKSIZE - HDRSIZE - 1; min_buf(haddr+ai); # #include "megatek.h" /* * copy matrix 1 to matrix 2: */ mcopy(m1,m2) float *m1 , *m2; { register int *rm1 , *rm2 , n; rm1 = m1; rm2 = m2; n = 32; while( n-- ) *rm2++ = *rm1++; } EGP , v); gtty(FDMEGP , v); v0 = v[0]; v[0] = v[2] = 0; stty(FDMEGP , v); return(v0); } 0177000); /* move to 0,0,0 */ min_buf(0010000); min_buf(0140000); min_buf(0040000); mrts(); /* first word in DL is a return! */ mflush_buf(); block[b].nleft = BLOCKSIZE - HDRSIZE - 1; min_buf(haddr+ai); # #include "megatek.h" /* * enter a transformation matrix in the current segment: */ mlocal(m) float *m; { enter_matrix(m); m_add(); } m2; n = 32; while( n-- ) *rm2++ = *rm1++; } EGP , v); gtty(FDMEGP , v); v0 = v[0]; v[0] = v[2] = 0; stty(FDMEGP , v); return(v0); } 0177000); /* move to 0,0,0 */ min_buf(0010000); min_buf(0140000); min_buf(0040000); mrts(); /* first word in DL is a return! */ mflush_buf(); block[b].nleft = BLOCKSIZE - HDRSIZE - 1; min_buf(haddr+ai); vmult(a , b , c) Purpose: Perform fast floating point vector-matrix multiplication. Arguments: a , c ... 4-element floating point arrays. b ... a 4x4 floating point matrix. Notes: The operation performed is [a] * [b] -> [c] . [a] and [c] may be the same array with no side effects. The quadrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quote new_window( iseg , xl , yb , xr , yt) Purpose: Reset a segment's window odefinition in the header. Arguments: iseg ... the segment number to change. xl, yb, xr, yt ... the lower-left and upper-right coordinates. Notes: All coordinates are in integer and in the range -2048 to 2047. quadrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quote mbutton( [arg] ) Purpose: Read the state of the joystick button. Argument: arg ... (optional) - If given, "mbutton" will sleep until the button is pushed. Notes: If "arg" is not given, "mbutton" will return immediately. Values returned are either 0 (button up) or 1 (button down). adrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quote mcopy( m1 , m2 ) Purpose: Copy one matrix into another. Arguments: m1 , m2 ... each a 4x4 floating matrix. mbutton" will sleep until the button is pushed. Notes: If "arg" is not given, "mbutton" will return immediately. Values returned are either 0 (button up) or 1 (button down). adrant rotation is in the range 0-3. Default quadrant rotation is 0 (parallel to the X axis). str should be typed "char *str". The string must end in a null character (if using the double quote mcrtget( x , y , iseg , prompt , max , array ) Purpose: Allow the user to enter a character string from the Megatek screen. Arguments: x , y ... the screen coordinates to place the prompt string and the user string. iseg ... the segment used to display this junk. prompt ... a string to be displayed as the prompt. If no prompt is desired, then one should specify mcrtget(...,"",...); "prompt" is of type char *. max ... the maximum number of characters to allow the victim to input. This is generally determined by the size of "array." array ... the address of a character array which will receive the string. This is of type char *. Notes: The entering of the string is terminated by a Carriage Return. Control-h is the backspace. The DEL key is the line delete. The returned string will have a null ('\0') replacing the Carriage Return. ,"",...); "prompt" is of type char *. max ... the maximum number of characters to allow the victim t mdir( xp , yp ) Purpose: Read the directions of the joystick. Arguments: xp , yp ... addresses of integer variables. Notes: Numbers in the range [-3,3] are returned. Calling sequence is: mdir(&ix,&iy); g is terminated by a Carriage Return. Control-h is the backspace. The DEL key is the line delete. The returned string will have a null ('\0') replacing the Carriage Return. ,"",...); "prompt" is of type char *. max ... the maximum number of characters to allow the victim t mdirections( xp , yp ) Purpose: Read the directions of the joystick. Arguments: xp , yp ... address of integer variables. Notes: Numbers returned are -16, -5, -1, 0, 1, 5, or 16. Calling sequence is: mdirections(&ix,&iy); a Carriage Return. Control-h is the backspace. The DEL key is the line delete. The returned string will have a null ('\0') replacing the Carriage Return. ,"",...); "prompt" is of type char *. max ... the maximum number of characters to allow the victim t meg_kb( [arg] ) Purpose: Read the state of the Megatek keyboard. Argument: arg ... (optional) - If given, "meg_kb" will sleep until a key is struck. Notes: If "arg" is not given, "meg_kb" will return immediately. Values returned are 8-bit Ascii. If "arg" is not given and no key has been struck, "meg_kb" returns 0. g will have a null ('\0') replacing the Carriage Return. ,"",...); "prompt" is of type char *. max ... the maximum number of characters to allow the victim t mlocal( m ) Purpose: Enter a transformation into the display list of the current segment. Argument: m ... a 4x4 floating matrix. Note: This will now supercede the matrix specified in the segment header by "new_matrix" for all subsequent vectors in the open segment. and no key has been struck, "meg_kb" returns 0. g will have a null ('\0') replacing the Carriage Return. ,"",...); "prompt" is of type char *. max ... the maximum number of characters to allow the victim t mmark() Purpose: Save the current state of the open segment. Arguments: None. Note: The current header and the current location of the end of the segment are saved. The header information includes initial intensity, transformation matrix, pseudo- origin, and window. Each segment can have only one mark; a second call to "mmark" will wipe out the first set of marked information. This is the converse of "mreset." ... the maximum number of characters to allow the victim t mreset() it was at the last call to "mmark." Arguments: None. Notes: Any display list that was entered after the last call to "mmark" will be demolished. Purpose: Reset the state of the open segment to what intensity, transformation matrix, pseudo- origin, and window. Each segment can have only one mark; a second call to "mmark" will wipe out the first set of marked information. This is the converse of "mreset." ... the maximum number of characters to allow the victim t# /* * opr - write to the CAD Lab's Lineprinter. * * %opr filename * % blah-blah...|opr * * will do some checking then spin itself off. * * Computer Aided Design and Graphics Lab * Purdue University * */ #define SI 0 /* standard input is to be used */ #define FILE 1 /* no, read from a file instead */ #define CNTL_S 023 #define BLANK 040 #define FORM 014 #define TAB 011 #define RIGHT 77 /* right-most column */ #define WAITSLEEP 1 /* how long to sleep between seeing if the line-printer is on line */ #define NTRIES 30 /* # times to try to see if the lp is on line */ #define LOCK "/tmp/lp_lock" /* if this file exists, then someone else printing */ #define LOCKSLEEP 15 /* # seconds to sleep waiting in line for the printer */ int fd 0; int fdout , in_flag; int old[3]; /* these are for gtty/stty */ int raw[3] {0 , 0 , 040}; char line[] {"/dev/tty1"}; char filebuf[518] , over_line[RIGHT] , statbuf[36]; char *ctime(); int column , overprint , tty , tvec[2]; struct { char name[8]; char tty; char dummy[7]; } utmp; /* character conversion tables: */ char chr[] { '{' , '}' , '|' , 0}; char sub1[] { '(' , ')' , '!' }; char sub2[] { '-' , '-' , ';' }; main(argc,argv) int argc; char *argv[]; { register char ch , *rcp; register int nfill; char c , *last_col , *name; int done() , pid , fdlock , fdtmp; extern int timezone , daylight; tty = ttyn(0); /* find what tty he is on */ timezone = 5*60*60; /* EST time */ daylight = 0; /* no DST */ time(tvec); /* get current time */ name = "????????"; /* to be used if cannot find login name */ if( argc>1 ) { in_flag=FILE; if( fopen(argv[1],filebuf) < 0 ) { printf("\n cannot open %s\7\n",argv[1]); exit(1); } } else in_flag=SI; /* now, fork it off */ if( (pid=fork()) != 0 ) { /* i'm the parent */ printf("\n %d\n",pid); exit(0); } if( (fdtmp=open("/etc/utmp",0)) > 0 ) while( read(fdtmp,&utmp,sizeof utmp) == sizeof utmp ) { if( tty != utmp.tty ) continue; name = &utmp.name; /* points to login name */ break; } close(fdtmp); for(;;) { while( stat(LOCK,statbuf) >= 0 ) { /* if >= 0, then someone else using printer */ sleep(LOCKSLEEP); } if( (fdlock=creat(LOCK,0666)) < 0 ) continue; write(fdlock," ",2); break; } if( (fdout=open(line,2)) < 0) { printf("\n cannot open %s\7\n",line); exit(1); } gtty(fdout,old); signal(2,&done); stty(fdout,raw); /* * wait for start signal from the line-printer: */ for(;;) { nfill = NTRIES; if( nfill-- == 0 ) { printf("\n Line Printer Not on Line!!\n\7"); done(); } if( empty(fdout) ) { /* line printer not talking */ sleep(WAITSLEEP); continue; /* try again */ } read(fdout,&c,1); if( c == ' ' ) /* looking for a blank */ break; } write1(FORM); crlfs(5); banner8(name); crlfs(5); writestr( ctime(tvec) ); if( in_flag==FILE ) { crlfs(5); writestr( argv[1] ); } if( (fdtmp=open("/etc/botd",0)) > 0 ) { crlfs(10); for(;;) { if( read(fdtmp,&c,1) <= 0 ) break; if( c == 012 ) write1(015); write1(c); } close(fdtmp); } write1(FORM); column = overprint = 0; blanks(); for(;;) { if( (ch=reader()) == 0 ) /* end-of-file */ break; if( ch == TAB ) { nfill = 4 - (column&03); while( nfill-- ) write1(' '); continue; } if( (ch&0177) == '\n' ) { if( overprint ) { write1(015); column = 0; rcp = &over_line[RIGHT]; while( *--rcp == ' ' ); /* find out where blanks end */ last_col = rcp; for(rcp= &over_line[0]; rcp<= last_col; rcp++) write1( *rcp ); /* print out overprint line */ overprint = 0; blanks(); } crlfs(1); continue; } write1(ch); } write1(FORM); printf("\n Print Completed"); done(); } reader() { register char c; if( in_flag==SI ) return( getchar() ); if( (c=getc(filebuf)) == -1 ) return(0); return(c); } /* * reset the line to cooked mode and exit: */ done() { stty(fdout,old); unlink( LOCK ); printf("\7"); exit(); } /* * check if lp is busy, write a character and increment the column count: */ write1(ch) { register char rch , rchr; register int j; char c; if( ch!=015 && ch!=012 && column>RIGHT ) return; if( 'a'<=ch && ch<='z' ) /* convert lower case to upper case */ ch=+ 'A'-'a'; if( empty(fdout) == 0 ) { /* the line-printer has a message */ read(fdout,&c,1); if( (c&0177) == CNTL_S ) /* ... and it says cool it! */ read(fdout,&c,1); /* wait and clear the input queue */ } /* character conversion: */ rch = ch; for(j=0; (rchr=chr[j]) != 0; j++) { if( rch == rchr ) { ch = sub1[j]; over_line[column] = sub2[j]; overprint++; break; } } write(fdout,&ch,1); if( ch != 012 ) column++; if( ch == 015 ) column = 0; } /* * fill the overprint buffer with blanks: */ blanks() { register char *rcp; for(rcp= &over_line[0]; rcp < &over_line[RIGHT]; rcp++) *rcp = ' '; } writestr(s) char *s; { register char *rcp , c; rcp = s; while( (c= *rcp++) ) write1(c); } /* * write several combinations: */ crlfs(n) { register int rn; if( (rn=n) <= 0 ) return; while( rn-- ) writestr("\015\012"); } /* * print out an eight-character banner heading: */ #define DEPTH 6 #define WIDTH 6 #define START ' ' #define END '_' #define ERR 'X' int tbl[] { 0, 0, 0, /* */ 020202, 04000, 0100000, /* ! */ 044440, 0, 0, /* " */ 045764, 0111375, 020000, /* # */ 075307, 0106665, 0160000, /* $ */ 03455, 05516, 0, /* % */ 030443, 012211, 0150000, /* & */ 020200, 0, 0, /* ' */ 010202, 04040, 040000, /* ( */ 020101, 02020, 0100000, /* ) */ 0443, 06110, 0, /* * */ 0101, 017420, 040000, /* + */ 0, 06020, 0100000, /* , */ 0, 017400, 0, /* - */ 0, 060, 0140000, /* . */ 02041, 04102, 0, /* / */ 030444, 0111110, 0140000, /* 0 */ 010301, 02021, 0170000, /* 1 */ 034420, 0102143, 0170000, /* 2 */ 0176021, 0103007, 0170000, /* 3 */ 010305, 037020, 040000, /* 4 */ 0177017, 0101407, 0160000, /* 5 */ 036417, 0120605, 0160000, /* 6 */ 0176020, 0102041, 0, /* 7 */ 075027, 0120605, 0160000, /* 8 */ 075030, 057413, 0140000, /* 9 */ 030300, 06060, 0, /* : */ 030300, 06020, 0100000, /* ; */ 0142, 010040, 060000, /* < */ 07, 0140174, 0, /* = */ 0601, 01021, 0100000, /* > */ 034023, 0104000, 0100000, /* ? */ 075031, 0124631, 0150000, /* @ */ 030450, 077606, 010000, /* A */ 0175037, 0120607, 0160000, /* B */ 075030, 020205, 0160000, /* C */ 0175030, 060607, 0160000, /* D */ 0177017, 0120203, 0170000, /* E */ 0177017, 0120202, 0, /* F */ 075030, 023605, 0160000, /* G */ 0103037, 0160606, 010000, /* H */ 010101, 02020, 040000, /* I */ 02020, 040605, 0160000, /* J */ 0103057, 022212, 010000, /* K */ 0101010, 020203, 0170000, /* L */ 0103473, 060606, 010000, /* M */ 0103432, 062616, 010000, /* N */ 075030, 060605, 0160000, /* O */ 0175030, 077202, 0, /* P */ 075030, 062611, 0150000, /* Q */ 0175030, 077212, 010000, /* R */ 075007, 0100605, 0160000, /* S */ 076101, 02020, 040000, /* T */ 0103030, 060605, 0160000, /* U */ 0103030, 060510, 0140000, /* V */ 0103030, 066716, 010000, /* W */ 0102443, 06112, 010000, /* X */ 042241, 02020, 040000, /* Y */ 0176041, 04103, 0170000, /* Z */ 034202, 04040, 0160000, /* [ */ 0100402, 02010, 010000, /* \ */ 070101, 02021, 0140000, /* ] */ 010240, 0, 0, /* ^ */ 0, 03, 0170000, /* _ */ }; char banner_line[100]; banner8( name8 ) char *name8; { register int i , j; register char *rcp; for(j=0; j END) x =& 0137; if (START <= x && x <= END) x =- START; else x = ERR - START; offset = shift / 16 + x * ((DEPTH * WIDTH + 15) / 16); shift =% 16; return(tbl[offset] >> (15 - shift) & 01); } ar *p, c; int n; p = buf; for (n = 0; n<8; n++) { c = s[n] & 0177; for (w = 0; w < WIDTH; w++) { *p++ = bit(c, row, w)? c : ' '; } *p++ = ' '; *p++ = ' '; } *p++ = 0; } bit(c, d, w) char c; int d, w; { register int shift, offset; register char x; shift = d * WIDTH + w; x = c; if (x > END) x =& 0137; if (START <= x && x <= END) x =- S rotm(matr , angx , angy , angz) Purpose: to create a transformation matrix of rotations. Arguments: matr ... the 4 x 4 transformation matrix. angx ... the rotation about the x axis (radians). angy ... the rotation about the y axis (radians). angz ... the rotation about the z axis (radians). Notes: The order of the rotation is angx - angy - angz. The previous contents of matr are lost. This is the converse of "mreset." ... the maximum number of characters to allow the victim t rotit(matr , angx , angy , angz) Purpose: To apply a rotational transformation to matr. Arguments: matr ... the 4 x 4 transformation matrix. angx ... the rotation about the x axis (radians). angy ... the rotation about the y axis (radians). angz ... the rotation about the z axis (radians). Notes: The order of rotation is angx - angy - angz. The effect of rotit is identical to the sequence: rotm(matrtem , angx , angy , angz) mmult(matr , matrtem , matr) allow the victim t transm(matr , delx , dely , delz) Purpose: to create a transformation matrix of translations. Arguments: matr ... the 4 x 4 transformation matrix. delx ... the translation along the x axis. dely ... the translation along the y axis. delz ... the translation along the z axis. Notes: The previous contents of matr are lost. - angy - angz. The effect of rotit is identical to the sequence: rotm(matrtem , angx , angy , angz) mmult(matr , matrtem , matr) allow the victim t scalem(matr , sclx , scly , sclz) Purpose: To create a scaling transformation matrix. Arguments: matr ... the 4 x 4 transformation matrix. sclx ... the scaling along the x axis. scly ... the scaling along the y axis. sclz ... the scaling along the z axis. Notes: The previous contents of matr are lost. lost. - angy - angz. The effect of rotit is identical to the sequence: rotm(matrtem , angx , angy , angz) mmult(matr , matrtem , matr) allow the victim t transit(matr , delx , dely , delz) Purpose: To apply a translational transformation to matr. Arguments: matr ... the 4 x 4 transformation matrix. delx ... the translation along the x axis. dely ... the translation along the y axis. delz ... the translation along the z axis. Notes: The effect of transit is identical to the sequence: transm(matrtem , delx , dely , delz) mmult(matr , matrtem , matr) em , angx , angy , angz) mmult(matr , matrtem , matr) allow the victim t scaleit(matr , sclx , scly , sclz) Purpose: To apply a scaling transformation to matr. Arguments: matr ... the 4 x 4 transformation matrix. sclx ... the scaling along the x axis. scly ... the scaling along the y axis. sclz ... the scaling along the z axis. Notes: The effect of scaleit is identical to the sequence: scalem(matrtem , sclx , scly , sclz) mmult(matr , matrtem , matr) matrtem , matr) em , angx , angy , angz) mmult(matr , matrtem , matr) allow the victim t float xx , yy , xn , yn; int ixn , iyn; double sin() , cos() , fabs(); int nc , ic , ii , ict , loc , iy; int nchar , ixn , iyn; register int i , i1 , itsub; if( (nc=count_char(str)) == 0) return; nchar = nc; th = theta*D2R; /* radians */ si = sin(th); co = cos(th); x=x1; y=y1; if( nc>=1 ) goto L50; fact=h/4.0; x=x-2.0*fact*(co-si); y=y-2.0*fact*(co+si); nc=1; if( nchar >= -1 ) goto L60; ic=2; goto L70; L50: fact=h/7.0; L60: ic=3; L70: xa=fact*co; ya=fact*si; xt=xa*6.0; yt=ya*6.0; for(i1=0; i1>3) & 07; if( xx==7.0 ) { ic=3; continue; } yy = iy & 07; xn = x + xa*xx - ya*yy; yn = y + ya*xx + xa*yy; ixn = 200.*xn; iyn = 200.*yn; mplot3(ixn , iyn , 0 , ic); ic=2; } x=+ xt; y=+ yt; ic=3; } } /* * count the # of chars in a string: */ count_char(str) char *str; { register char *rcp; rcp = str; while(*rcp != 0) rcp++; return(rcp-str); } if( (ict=kct[itsub]) == 0) break; loc = koc[itsub]; for(i=0;i>3) & 07; if( xx==7.0 ) { ic=3; continue; } yy = iy & 07; xn = x + xa*xx - ya*yy; yn = y + ya*xx + xa*yy; ixn = 200.*xn; iyn = 200.*yn; mplot3(ixn , iyn , 0 , ic); ic=2; } x=+ xt; y=+ yt; ic=3; } } /*# /* * set the screen window on the megatek: * (coords are -+ 2048) */ mwindow(xl,yb,xr,yt) { #include "externs.h" min_buf( maddr ); mclip(xl,yb,xr,yt); m_add(); } == 0) break; loc = koc[itsub]; for(i=0;i>3) & 07; if( xx==7.0 ) { ic=3; continue; } yy = iy & 07; xn = x + xa*xx - ya*yy; yn = y + ya*xx + xa*yy; ixn = 200.*xn; iyn = 200.*yn; mplot3(ixn , iyn , 0 , ic); ic=2; } x=+ xt; y=+ yt; ic=3; } } /*# #include "megatek.h" /* * change the transformation matrix in the header of seg #iseg: */ new_matrix(iseg , m) float *m; { register char *addr; register int b; #include "externs.h" if( iseg<=0 || iseg>NSEGS ) { printf("\n new_matrix - seg # out of range!\n\7"); return; } if( (b=segs[iseg].s_index) <= 0 ) { printf("\n new_matrix - seg %d not open yet!\n\7",iseg); return; } addr = block[b].addr; /* address of seg header */ min_buf( addr+5 ); enter_matrix(m); mflush_buf(); } } /*# #include "megatek.h" /* * change the clipping coordinates in the header of seg #iseg: */ new_window(iseg , xl , yb , xr , yt) { register char *addr; register int b; #include "externs.h" if( iseg<=0 || iseg>NSEGS ) { printf("\n new_window - seg # out of range!\n\7"); return; } if( (b=segs[iseg].s_index) <= 0 ) { printf("\n new_window - seg %d not open yet!\n\7",iseg); return; } addr = block[b].addr; /* address of seg header */ min_buf( addr+14 ); mclip(xl , yb , xr , yt); mflush_buf(); } e "megatek.h" /* * change the clipping coordinates in the header of seg #iseg: */ new_window(iseg , xl , yb , xr , yt) { register char *addr; register int b; #include "externs.h" if( iseg<=0 || iseg>NSEGS ) { printf("\n new_window - seg # out of range!\n\7"); return; } if( (b=segs[iseg].s_index) <= 0 ) { printf("\n new_window - seg %d not open yet!\n\7",iseg); return; } addr = block[b].addr; /* address of seg header */ min_buf( addr+14 ); mclip(xl , yb , xr , yt); mflush_# #include "megatek.h" /* * return a block to the free list: */ return_free(f) { #include "externs.h" if( f<0 || f>NBLOCKS-1 ) return; block[f].next = m_free; m_free = f; } externs.h" if( iseg<=0 || iseg>NSEGS ) { printf("\n new_window - seg # out of range!\n\7"); return; } if( (b=segs[iseg].s_index) <= 0 ) { printf("\n new_window - seg %d not open yet!\n\7",iseg); return; } addr = block[b].addr; /* address of seg header */ min_buf( addr+14 ); mclip(xl , yb , xr , yt); mflush_/*********************************************************************** /* /* vmult(a,b,c) - perform floating matrix-vector multiply /* /* adapted from a similar routine written by D. Anderson /* /* made for FLOAT (4 bytes per fp number) matrices only! /* /* [a] * [b] -> [c] /* ( [c] may be [a] if n=l ) /* /* [a] is 1xn /* [b] is nxl /* [c] is 1xl /* /* /* Mike Bailey - May 1979 /* /* /*********************************************************************** .globl _vmult .text _vmult: ~~vmult: / save regs: mov r0,-(sp) mov r1,-(sp) mov r2,-(sp) mov r3,-(sp) mov r4,-(sp) mov r5,-(sp) mov sp,r5 / matrix sizes: n = 4 l = 4 / offsets from r5 after storing user regs: a = 16 b = 20 c = 22 mov a(r5),r0 mov b(r5),r1 add $n*4,r0 /end of [a] matrix + 1 add $n*l*4,r1 /end of [b] matrix + 1 mov r1,bend 1: mov $l,r4 2: mov $n,r3 /# pairs to multiply clr -(sp) clr -(sp) / set stack to 0.0 3: mov -(r0),-(sp) mov -(r0),-(sp) / push [a] element on the stack beq 7f /skip a lot of stuff if == 0.0 mov -(r1),-(sp) mov -(r1),-(sp) / push [b] element on the stack beq 8f / skip a lot if == 0.0 fmul sp / multiply the 2 elements fadd sp / add to sum already on stack (leave on stack) 4: sub $4*l-4,r1 / point [b] to one row less sob r3,3b / multiply n pairs / done multiplying one element of c: add $4*n*l-4,r1 / update [b] pointer add $4*n,r0 / update [a] pointer sob r4,2b / do until can move up one row of [a] / done multiplying - extract [c] from stack: mov c(r5),r2 mov $2*l,r4 /counter 5: mov (sp)+,(r2)+ sob r4,5b / restore registers and return: mov r5,sp mov (sp)+,r5 mov (sp)+,r4 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,r1 mov (sp)+,r0 rts pc 7: cmp (sp)+,(sp)+ cmp -(r1),-(r1) br 4b 8: add $8.,sp br 4b .globl fltused fadd = 075000^rts fmul = 075020^rts .comm ac0,8. .globl .bss bend: .=.+2 inter add $4*n,r0 / update [a] pointer sob r4,2b / do until can move up one row of [a] / done multiplying - extract [c] from stack: mov# #include "megatek.h" /* * wait for any peripheral to be struck and return its word: */ wait_event() { register int v0; int v[3]; #include "externs.h" v[2] = 0; v[0] = WAIT; stty(FDMEGP , v); gtty(FDMEGP , v); v0 = v[0]; v[0] = v[2] = 0; stty(FDMEGP , v); return(v0); } fadd = 075000^rts fmul = 075020^rts .comm ac0,8. .globl .bss bend: .=.+2 inter add $4*n,r0 / update [a] pointer sob r4,2b / do until can move up one row of [a] / done multiplying - extract [c] from stack: movlag.proj++; continue; case VIEW4: mseg(-LCURS3D); mseg(-RCURS3D); mblank(OBJECT); mseg(TMP); mplot2( (LEFT+RIGHT)/2 , BOTTOM , 3); mplot2( (LEFT+RIGHT)/2 , TOP , 2); mplot2( LEFT , (TOP+BOTTOM)/2 , 3); mplot2( RIGHT , (TOP+BOTTOM)/2 , 2); menu1[VIEW4].ints = 0; menu1[VIEW1].ints = menu1[VIEW2].ints = 15; chg_view( VIEW4 ); mblank(-CURS3D); new_window(CURS3D , (LEFT+RIGHT)/2 , (TOP+BOTTOM)/2 , RIGHT , TOP); update_curs(); plot_menu(&menu1); flag.proj++; continue; case ADD: add(); plot_menu( &menu1 ); continue; case PARAMETERS: if( (p=get_pltch()) == 0 ) continue; parameters(p); plot_menu( &menu1 ); continue; case COMPACT: compact(); continue; case FILL: draw_traces(); menu1[FILL].ints = 0; menu1[UNFILL].ints = 15; plot_menu( &menu1 ); continue; case UNFILL: mappend( TRACES ); mreset(); menu1[FILL].ints = 15; menu1[UNFILL].ints = 0; plot_menu( &menu1 ); continue; case WAIT: mseg( MESG ); mplot2(MESGX , MESGY , 3); mstring(MESGSCL , "Waiting . . ."); burp(); waitez(); /* wait for last job spun off */ menu1[WAIT].ints = 0; plot_menu( &menu1 ); mesg("You're Back!"); continue; } /* didn't find a menu item - test if specifying a point: */ mmouse(&ix , &iy); if( (p=hit_pt(ix,iy)) == 0 ) /* found nothing */ continue; point = p; markit( point ); /* mark every point found */ update_curs(); /* move 3D cursor */ continue; transform: make_xform(); switch( flag.view ) { case VIEW1: p = &xform[0][0]; new_matrix(OBJECT , p); break; case VIEW2: mmult(xform , &quarters[STLEFT][0] , m1); mmult(xform , &quarters[STRIGHT][0] , m2); new_matrix( STLEFT , m1 ); new_matrix( STRIGHT , m2 ); p = &m2[0][0]; break; case VIEW4: mmult(xform , &quarters[UPPERRIGHT][0] , m1); p = &m1[0][0]; new_matrix(UPPERRIGHT , p); break; } new_matrix(CTLPTS , p); new_matrix(MARKER , p); update_curs(); flag.proj++; continue; } } /* * separate menu to take care of adding things to the object: */ add() { register int j; plot_menu( &menu4 ); for(EVER) { switch( (j=loop(&menu4)) ) { case EXIT: return; case ADDPT: x_3d = point->x; y_3d = point->y; z_3d = point->z; add_pt(); continue; case ADDLINE: add_line(); continue; case ADDCRV: continue; case ADDARC: add_arc(); continue; case ADDPLTCH: continue; } } } /* * add an arc to the data structure: */ add_arc() { register char *p; if( num_m < 3 ) { mesg("Need 3 Marks"); return; } p = alloc(sizeof arc); num_a++; get_last( &arc )->nexta = p; p->c = ( p->a2= (p->a1= mark.mark) ->mark) ->mark; p->nexta = 0; mappend(OBJECT); draw_arc(p); flag.write++; } /* * add a line to the data structure: */ add_line() { register char *p; if( num_m < 2 ) { mesg("Need 2 Marks"); return; } p = alloc(sizeof line); num_l++; get_last( &line )->nextl = p; p->l2 = (p->l1= mark.mark) ->mark; p->nextl = 0; mappend(OBJECT); draw_line(p); flag.write++; } /* * add a point to the data structure - make it the current point (ie, variable "point"): * ( make its coords the same as the 3D cursor's ) */ add_pt() { register char *p; p = point = alloc(sizeof vert); num_v++; p->x = x_3d; p->y = y_3d; p->z = z_3d; p->mark = 0; project(p); /* fill p->sx, p->sy */ get_last( &vert )->nextv = p; /* link in */ p->nextv = 0; flag.write++; } /* * allocate free space / remove free space: */ char *alloc(asize) int asize; { register int size; register char *p , *pp; char *sbrk(); size=asize; size++; size=& ~1; /* be sure size is even */ for(p= &free; p->next!=0; p=p->next) { if( p->next->nbytes==size ) { /* perfect fit! */ pp=p->next; p->next = p->next->next; /* un-link this block */ return(pp); } if( p->next->nbytes > size+2 ) { /* too big so will use part of it */ pp = p->next+size; /* take front part of free block */ pp->next = p->next->next; pp->nbytes = p->next->nbytes; p->next = pp; pp=- size; /* old "p->next" */ return(pp); } } /* nothing fit - try sbrk */ if( (p=sbrk(size)) == -1 ) { printf("\n Out of Room!\7\n"); exit(1); } return(p); } unalloc(ap , asize) char *ap; int asize; { register char *p , *pp; pp=ap; pp->nbytes = asize; for(p= &free; p->next!=0; p=p->next) if( p->next > pp ) break; /* new block should be linked after p: */ pp->next = p->next; p->next = pp; /* try to consolidate blocks after and before: */ if( pp->next != 0 ) { /* ie, new block isn't last in the list */ if( pp+pp->nbytes==pp->next ) { pp->nbytes=+ pp->next->nbytes; pp->next = pp->next->next; } } if( p != &free ) { /* ie, new block is not first in the list */ if( p+p->nbytes==pp ) { p->nbytes=+ pp->nbytes; p->next = pp->next; } } } /* * print a beep at the decwriter: */ burp() { static int fdtty8; /* file descriptor for decwriter */ if( fdtty8 == 0 ) { /* must open first! */ if( (fdtty8=open("/dev/tty8",1)) < 0 ) { printf("\n cannot open /dev/tty8!\n\7"); exit(1); } } write( fdtty8 , "\7" , 1 ); } /* * plot a string centered about a given point: */ center_string(as , ix , iy , is) char *as; int ix , iy , is; { register char *s; register int n , scl; scl = is; /* scale factor should be 0-7 */ scl=& 07; s = as; n = count_char( s ); scl++; mplot2(ix-n*6*scl , iy-9*scl , 3); mstring(--scl , s); } /* * change the view without re-drawing the object: */ chg_view( v ) { register int j , view; view = v; mblank(OBJECT); switch( view ) { case VIEW1: flag.view=VIEW1; for(j=LOWERLEFT; j<=STRIGHT; j++) mseg(-j); new_matrix(CTLPTS , xform); new_matrix(MARKER , xform); new_matrix(OBJECT , xform); new_window(OBJECT , LEFT , BOTTOM , RIGHT , TOP); new_window(CTLPTS , LEFT , BOTTOM , RIGHT , TOP); new_window(MARKER , LEFT , BOTTOM , RIGHT , TOP); mblank(-OBJECT); return; case VIEW2: flag.view=VIEW2; for(j=LOWERLEFT; j<=LOWERRIGHT; j++) mseg(-j); mmult(xform , &quarters[STLEFT][0] , m1); mmult(xform , &quarters[STRIGHT][0] , m2); new_matrix(CTLPTS , m2); new_window( CTLPTS , (LEFT+RIGHT)/2 , BOTTOM , RIGHT , TOP); new_window( MARKER , (LEFT+RIGHT)/2 , BOTTOM , RIGHT , TOP); new_matrix(MARKER , m2); mseg(STLEFT); new_matrix(STLEFT , m1); new_window( STLEFT , LEFT , BOTTOM , (LEFT+RIGHT)/2 , TOP); mgetsub(OBJECT); mseg(STRIGHT); new_matrix(STRIGHT , m2); new_window( STRIGHT , (LEFT+RIGHT)/2 , BOTTOM , RIGHT , TOP); mgetsub(OBJECT); return; case VIEW4: flag.view = VIEW4; for(j=STLEFT; j<=STRIGHT; j++) mseg(-j); mmult(xform , &quarters[UPPERRIGHT][0] , m1); new_matrix(CTLPTS , m1); new_matrix(MARKER , m1); new_window( CTLPTS , (LEFT+RIGHT)/2 , (BOTTOM+TOP)/2 , RIGHT , TOP); new_window( MARKER , (LEFT+RIGHT)/2 , (BOTTOM+TOP)/2 , RIGHT , TOP); for(j=LOWERLEFT; j<=LOWERRIGHT; j++) { mseg(j); new_matrix(j , (j==UPPERRIGHT) ? &m1[0][0] : &quarters[j][0]); if( j==UPPERRIGHT ) new_window( j , (LEFT+RIGHT)/2 , (BOTTOM+TOP)/2 , RIGHT , TOP); mgetsub(OBJECT); } return; } } /* * compact the data structure, removing redundant pts, lines, curves, and arcs: */ compact() { register char *p1 , *p2 , *p; char *last; int j , changed; changed = 0; /* !=0 means something changed */ for(p1=vert.nextv; p1!=0; p1=p1->nextv) { last = p1; for(p2=p1->nextv; p2!=0; p2= (last=p2)->nextv) { if( abs(p2->x - p1->x) > TOL ) continue; if( abs(p2->y - p1->y) > TOL ) continue; if( abs(p2->z - p1->z) > TOL ) continue; /* remove point given by p2: */ for(p=line.nextl; p!=0; p=p->nextl) { if( p->l1==p2 ) p->l1=p1; if( p->l2==p2 ) p->l2=p1; } for(p=crv.nextc; p!=0; p=p->nextc) { if( p->c1==p2 ) p->c1=p1; if( p->c2==p2 ) p->c2=p1; if( p->c3==p2 ) p->c3=p1; if( p->c4==p2 ) p->c4=p1; } for(p=arc.nexta; p!=0; p=p->nexta) { if( p->a1==p2 ) p->a1=p1; if( p->a2==p2 ) p->a2=p1; if( p->c==p2 ) p->c=p1; } last->nextv = p2->nextv; /* link around point being removed */ num_v--; if( p2->mark ) un_markit( p2 ); unalloc(p2 , sizeof vert); p2 = last; /* fool the "for" */ changed++; burp(); } } /* remove duplicate lines: */ for(p1=line.nextl; p1!=0; p1=p1->nextl) { last = p1; for(p2=p1->nextl; p2!=0; p2= (last=p2)->nextl) { if( (p1->l1==p2->l1 && p1->l2==p2->l2) || (p1->l1==p2->l2 && p1->l2==p2->l1) ) { for(p=pltch.nextpl; p!=0; p=p->nextpl) { for(j=0; jnsides; j++) { if( p->side[j].what==LINE && p->side[j].which==p2 ) p->side[j].which=p1; } } last->nextl = p2->nextl; num_l--; unalloc(p2 , sizeof line); p2=last; changed++; burp(); } } } /* remove duplicate curves */ for(p1=crv.nextc; p1!=0; p1=p1->nextc) { last = p1; for(p2=p1->nextc; p2!=0; p2= (last=p2)->nextc) { if( p1->whatc!=p2->whatc ) continue; /* curves aren't even the same type */ if( (p1->c1==p2->c1 && p1->c2==p2->c2 && p1->c3==p2->c3 && p1->c4==p2->c4) || (p1->c1==p2->c4 && p1->c2==p2->c3 && p1->c3==p2->c2 && p1->c4==p2->c1) ) { for(p=pltch.nextpl; p!=0; p=p->nextpl) { for(j=0; jnsides; j++) { if( p->side[j].what==CURVE && p->side[j].which==p2 ) p->side[j].which = p1; } } last->nextc = p2->nextc; num_c--; unalloc(p2 , sizeof crv); p2=last; changed++; burp(); } } } /* remove duplicate arcs: */ for(p1=arc.nexta; p1!=0; p1=p1->nexta) { last = p1; for(p2=p1->nexta; p2!=0; p2= (last=p2)->nexta) { if( p1->c != p2->c ) continue; if( (p1->a1==p2->a1 && p1->a2==p2->a2) || (p1->a1==p2->a2 && p1->a2==p2->a1) ) { for(p=pltch.nextpl; p!=0; p=p->nextpl) { for(j=0; jnsides; j++) { if( p->side[j].what==ARC && p->side[j].which==p2 ) p->side[j].which=p1; } } last->nexta = p2->nexta; num_a--; unalloc(p2 , sizeof arc); p2=last; changed++; burp(); } } } /* Done! */ if( changed ) { mesg("Done!"); draw_all(); } else mesg("Nothing Changed!"); } /* * count the elements in a particular linked list: * (this is possible only because the "next" pointer is always the first word!) */ count(start) char *start; { register char *p; register int j; j=0; for(p=start->next; p!=0; p=p->next) j++; return(j); } /* * count the chars in a string: */ count_char(as) char *as; { register char *s1 , *s2; s1 = s2 = as; while( *s2 ) s2++; return(s2-s1); } /* * integer cross-product: */ cross_product(v1 , v2 , v3) int *v1 , *v2 , *v3; { register int *a , *b , *c; a=v1; b=v2; c=v3; c->fx = a->fy*b->fz - b->fy*a->fz; c->fy = b->fx*a->fz - a->fx*b->fz; c->fz = a->fx*b->fy - b->fx*a->fy; } /* * separate menu for deleting things: */ delete() { register int j; register char *p; plot_menu( &menu3 ); for(EVER) { switch( (j=loop(&menu3)) ) { case EXIT: return; case DELPT: p = point->nextv; del_pt( point ); if( (point=p) == 0 ) point = vert.nextv; if( point==0 ) { /* out of points */ printf("\n Out of points!\n\7\7"); exit(1); /* for now */ } update_curs(); /* draw 3D cursor at new location */ draw_all(); /* draw the object with the point gone */ continue; case DELBOUNDARY: del_bound(); continue; case DELPLTCH: del_pltch(); continue; } } } /* * change sines and cosines to reflect a change in angle: */ delta_ang(axis) { float c , cd , sd; cd = cdtheta; sd = sdtheta; if( axis < 0 ) { sd = -sd; axis = -axis; } switch( axis ) { case X: c = cosx*cd - sinx*sd; sinx = sinx*cd + cosx*sd; cosx = c; break; case Y: c = cosy*cd - siny*sd; siny = siny*cd + cosy*sd; cosy = c; break; case Z: c = cosz*cd - sinz*sd; sinz = sinz*cd + cosz*sd; cosz = c; break; } } /* * delete the given boundary curve and any platches that use it: */ del_bound() { register char *p , *p1 , *p2; int what , j; char *last; if( num_m < 2 ) { mesg("Need 2 Marks"); return; } p2 = (p1= mark.mark)->mark; what=LINE; last= &line; for(p=line.nextl; p!=0; p= (last=p)->nextl ) if( (p->l1==p1 && p->l2==p2) || (p->l1==p2 && p->l2==p1) ) goto foundit; what = CURVE; last= &crv; for(p=crv.nextc; p!=0; p= (last=p)->nextc ) if( (p->c1==p1 && p->c4==p2) || (p->c1==p2 && p->c4==p1) ) goto foundit; what = ARC; last= &arc; for(p=arc.nexta; p!=0; p= (last=p)->nexta ) if( (p->a1==p1 && p->a2==p2) || (p->a1==p2 && p->a2==p1) ) goto foundit; mesg("No Boundary Curve Found"); return; foundit: last->next = p->next; /* link around it */ switch( what ) { case LINE: num_l--; unalloc(p , sizeof line); break; case CURVE: num_c--; unalloc(p , sizeof crv); break; case ARC: num_a--; unalloc(p , sizeof arc); break; } last= &pltch; for(p1=pltch.nextpl; p1!=0; p1= (last=p1)->nextpl) { for(j=0; jnsides; j++) { if( p1->side[j].which==p ) { last->nextpl = p1->nextpl; unalloc(p1 , sizeof pltch); p1 = last; num_pl--; break; } } } draw_all(); } /* * delete the given platch: */ del_pltch() { register char *p , *pl , *last; if( (p=get_pltch()) == 0) { mesg("No Platch Found"); return; } last= &pltch; for(pl=pltch.nextpl; pl!=p; pl= (last=pl)->nextpl); last->nextpl = p->nextpl; num_pl--; unalloc(p , sizeof pltch); draw_all(); return; } /* * delete the given point and thus all structures associated with it: */ del_pt( pt ) struct vert *pt; { register struct vert *pnt; register char *p , *last; int j; char *pp; pnt = pt; zero_flags(); if( pnt->mark ) { /* eliminate marked state if it's marked */ for(p= &mark; p->mark!= pnt; p=p->mark); p->mark = pnt->mark; draw_marks(); } for( p= (last= &pltch)->nextpl; p!=0; p= (last=p)->nextpl ) { for(j=0; jnsides; j++) { pp = p->side[j].which; switch( p->side[j].what ) { case LINE: if( pp->l1==pnt || pp->l2==pnt ) p->flagpl++; break; case CURVE: if(pp->c1==pnt || pp->c2==pnt || pp->c3==pnt || pp->c4==pnt) p->flagpl++; break; case ARC: if( pp->a1==pnt || pp->a2==pnt || pp->c==pnt ) p->flagpl++; break; } if( p->flagpl ) break; } if( p->flagpl ) { last->nextpl = p->nextpl; /* link around this structure */ unalloc(p , sizeof pltch); p = last; /* fool the "for" */ num_pl--; } } for( p= (last= &line)->nextl; p!=0; p= (last=p)->nextl ) if( p->l1==pnt || p->l2==pnt ) { last->nextl = p->nextl; unalloc(p , sizeof line); p=last; num_l--; } for( p= (last= &crv)->nextc; p!=0; p= (last=p)->nextc ) if( p->c1==pnt || p->c2==pnt || p->c3==pnt || p->c4==pnt ) { last->nextc = p->nextc; unalloc(p , sizeof crv); p=last; num_c--; } for( p= (last= &arc)->nexta; p!=0; p= (last=p)->nexta ) if( p->a1==pnt || p->a2==pnt || p->c==pnt ) { last->nexta = p->nexta; unalloc(p , sizeof arc); p=last; num_a--; } for( p= (last= &vert)->nextv; p!=0; p= (last=p)->nextv ) { if( p!= pnt ) continue; last->nextv = p->nextv; unalloc(p , sizeof vert); num_v--; break; } flag.write++; /* indicate a change has been made */ } /* * store the data in the outfile: */ done( filename ) char *filename; { register char *p; register int i , j; char *fp; if( nargs() <= 0 ) filename = outfile; /* just in case */ close( iobuf[0] ); /* want to re-use iobuf */ if( fcreat(filename , iobuf) < 0 ) { printf("\n cannot create %s \7\n", filename); return; } putw(num_v , iobuf); putw(num_pl , iobuf); putw(num_l , iobuf); putw(num_c , iobuf); putw(num_a , iobuf); for(p=vert.nextv; p!=0; p=p->nextv) { putw(p->x , iobuf); putw(p->y , iobuf); putw(p->z , iobuf); } for(p=pltch.nextpl; p!=0; p=p->nextpl) { putw(p->nsides , iobuf); putw(p->color , iobuf); fp = &p->transparency; putw(fp->high , iobuf); putw(fp->low , iobuf); for(j=0; jnsides; j++) { putw( (i=p->side[j].what) , iobuf ); switch( i ) { case LINE: putw( i_th(&line,p->side[j].which) , iobuf ); break; case CURVE: putw( i_th(&crv,p->side[j].which) , iobuf ); break; case ARC: putw( i_th(&arc,p->side[j].which) , iobuf ); break; } } } for(p=line.nextl; p!=0; p=p->nextl) { putw( i_th(&vert,p->l1) , iobuf); putw( i_th(&vert,p->l2) , iobuf); } for(p=crv.nextc; p!=0; p=p->nextc) { putw( p->whatc , iobuf ); putw( i_th(&vert,p->c1) , iobuf); putw( i_th(&vert,p->c2) , iobuf); putw( i_th(&vert,p->c3) , iobuf); putw( i_th(&vert,p->c4) , iobuf); } for(p=arc.nexta; p!=0; p=p->nexta) { putw( i_th(&vert,p->a1) , iobuf ); putw( i_th(&vert,p->a2) , iobuf ); putw( i_th(&vert,p->c) , iobuf ); } fflush( iobuf ); mesg("Done!"); } /* * draw the 3D cursor: */ draw3d() { register int half; half = LABEL>>1; /* half the given length */ mseg( CURS3D ); switch( flag.view ) { case VIEW1: new_window(CURS3D , LEFT , BOTTOM , RIGHT , TOP); break; case VIEW2: mblank(CURS3D); break; case VIEW4: new_window(CURS3D , (LEFT+RIGHT)/2 , (TOP+BOTTOM)/2 , RIGHT , TOP ); break; } mplot3(-LNGTH3D,0,0,3); mplot3(LNGTH3D,0,0,2); mrplot3(AFTER,0,0,3); mrplot3(LABEL,LABEL,0,2); mrplot3(-LABEL,0,0,3); mrplot3(LABEL,-LABEL,0,2); mplot3(0,-LNGTH3D,0,3); mplot3(0,LNGTH3D,0,2); mrplot3(0,AFTER,0,3); mrplot3(0,half,0,2); mrplot3(half,half,0,2); mrplot3(-LABEL,0,0,3); mrplot3(half,-half,0,2); mplot3(0,0,-LNGTH3D,3); mplot3(0,0,LNGTH3D,2); mrplot3(0,0,AFTER,3); mrplot3(0,0,LABEL,2); mrplot3(0,LABEL,-LABEL,2); mrplot3(0,0,LABEL,2); } /* * draw the entire display: */ draw_all() { register char *p; register int j; switch( flag.view ) { case VIEW2: mmult(xform , &quarters[STLEFT][0] , m1); mmult(xform , &quarters[STRIGHT][0] , m2); break; case VIEW4: mmult(xform , &quarters[UPPERRIGHT][0] , m1); /* transform for upper right corner */ break; } zero_flags(); /* set all flags to 0 so don't draw a line twice */ mseg( -CTLPTS); /* turn off ctl pts */ mseg( MESG ); mplot2(MESGX , MESGY , 3); mstring(MESGSCL , "Drawing . . ."); burp(); mseg( OBJECT ); new_matrix(OBJECT , xform); mblank(OBJECT); if( flag.view==VIEW1 ) new_window( OBJECT , LEFT , BOTTOM , RIGHT , TOP); for(p=pltch.nextpl; p!=0; p=p->nextpl) if( p->flagpl==0 ) { p->flagpl++; draw_pl( p ); } for(p= line.nextl; p!=0; p=p->nextl) if( p->flag==0 ) { p->flag++; draw_line(p); } for(p=crv.nextc; p!=0; p=p->nextc) if( p->flag==0 ) { p->flag++; draw_crv(p); } for(p=arc.nexta; p!=0; p=p->nexta) if( p->flag==0 ) { p->flag++; draw_arc(p); } mgetsub( TRACES ); mintsty(15); /* intensity for moving */ mmark(); /* mark for moving */ /* draw the control points: */ mseg(CTLPTS); switch( flag.view ) { case VIEW1: new_matrix(CTLPTS , xform); new_window(CTLPTS , LEFT , BOTTOM , RIGHT , TOP); break; case VIEW2: new_matrix(CTLPTS , m2); new_window(CTLPTS , (LEFT+RIGHT)/2 , BOTTOM , RIGHT , TOP); break; case VIEW4: new_matrix(CTLPTS , m1); new_window(CTLPTS , (LEFT+RIGHT)/2 , (TOP+BOTTOM)/2 , RIGHT , TOP); break; } for(p=crv.nextc; p!=0; p=p->nextc) { switch( p->whatc ){ case BZ: case OH: point_plot(p->c2 , p->c3); break; } } mseg( -MESG ); if( flag.view==VIEW1 ) { mblank(-OBJECT); return; } /* do stereopairs: */ if( flag.view == VIEW2 ) { mseg(STLEFT); new_matrix(STLEFT , m1); new_window(STLEFT , LEFT , BOTTOM , (LEFT+RIGHT)/2 , TOP); mgetsub(OBJECT); mseg(STRIGHT); new_matrix(STRIGHT , m2); new_window(STRIGHT , (LEFT+RIGHT)/2 , BOTTOM , RIGHT , TOP); mgetsub(OBJECT); return; } /* initialize the 4 corners */ for(j=LOWERLEFT; j<=LOWERRIGHT; j++) { mseg(j); new_matrix(j , (j==UPPERRIGHT) ? &m1[0][0] : &quarters[j][0]); if( j==UPPERRIGHT ) new_window(j , (LEFT+RIGHT)/2 , (BOTTOM+TOP)/2 , RIGHT , TOP); mgetsub(OBJECT); } } /* * draw the given arc: */ float cda { 0.996 } , sda { 0.087 }; /* these are for 5 degrees */ draw_arc(aap) char *aap; { register char *ap; char *vp; register int j , x; int y , z , a[3] , b[3] , c[3]; float cosa , sina , newc; ap = aap; for(j=0; j<3; j++) { c[j] = ap->c->coord[j]; /* center */ a[j] = ap->a1->coord[j] - c[j]; /* relative to center */ b[j] = ap->a2->coord[j] - c[j]; } cosa = 1.0; sina = 0.0; /* start at 0 degrees */ vp = ap->a1; mplot3(vp->x , vp->y , vp->z , 3); for(j=0; j<18; j++) { newc = cosa*cda - sina*sda; sina = sina*cda + cosa*sda; cosa = newc; x = cosa*a[0] + sina*b[0] + c[0]; y = cosa*a[1] + sina*b[1] + c[1]; z = cosa*a[2] + sina*b[2] + c[2]; mplot3(x,y,z , 2); } } /* * draw the given curve: */ #define NSTEPS 10 /* # line segments in each curve */ draw_crv(acp) char *acp; { register char *cp , *vp; register int j; int i; float t , tt[4] , xyz[4] , dt; int c1 , c2 , c3 , c4; cp = acp; switch( cp->whatc ) { case BZ: for(j=0; j<3; j++) { c1 = cp->c1->coord[j]; c2 = cp->c2->coord[j]; c3 = cp->c3->coord[j]; c4 = cp->c4->coord[j]; m3[0][j] = -c1 + 3*c2 - 3*c3 + c4; m3[1][j] = 3*(c1-c2-c2+c3); m3[2][j] = 3*(c2-c1); m3[3][j] = c1; m3[j][3] = 0.0; } m3[3][3] = 1.0; break; case OH: for(j=0; j<3; j++) { m3[0][j] = cp->c2->coord[j]; m3[1][j] = cp->c1->coord[j]; m3[2][j] = cp->c4->coord[j]; m3[3][j] = cp->c3->coord[j]; m3[j][3] = 0.0; } m3[3][3] = 0.; mmult(ohmat , m3 , m3); break; } /* multiply by the [t**3 t**2 t 1] vector: */ t = 0.0; dt = 1.0/NSTEPS; tt[3] = 1.0; vp = cp->c1; /* vp points to the first point */ mplot3( vp->x , vp->y , vp->z , 3); for(i=0; il1; pv2=lp->l2; mplot3( pv1->x , pv1->y , pv1->z , 3); mplot3( pv2->x , pv2->y , pv2->z , 2); } /* * draw the little cubes at all marked points: */ char mstr[] {"00"}; draw_marks() { register char *p; register int i , j; mseg(MARKER); switch( flag.view ) { case VIEW1: new_matrix(MARKER , xform); break; case VIEW2: mmult(xform , &quarters[STRIGHT][0] , m1); new_matrix(MARKER , m1); break; case VIEW4: mmult(xform , &quarters[UPPERRIGHT][0] , m1); new_matrix(MARKER , m1); break; } i = j = 0; num_m = 0; for(p=mark.mark; p!= -1; p=p->mark) { mplot3(p->x , p->y , p->z , 3); mgetsub( SMALLCUBE ); mstr[0] = '0' + i; mstr[1] = '0' + j; if( ++j == 9 ) { i++; j=0; } if( mstr[0]=='0' ) mstr[0] = ' '; mstring(1 , mstr); num_m++; } } /* * only draw the lines, curves, and arcs that are affected by a given point: */ draw_only(apv) char *apv; { register char *pv , *p; pv=apv; zero_flags(); for(p=line.nextl; p!=0; p=p->nextl) if( p->l1==pv || p->l2==pv ) if( p->flag==0 ) { p->flag++; draw_line(p); } for(p=crv.nextc; p!=0; p=p->nextc) if( p->c1==pv || p->c2==pv || p->c3==pv || p->c4==pv ) if( p->flag==0 ) { p->flag++; draw_crv(p); } for(p=arc.nexta; p!=0; p=p->nexta) if( p->a1==pv || p->a2==pv || p->c==pv ) if( p->flag==0 ) { p->flag++; draw_arc(p); } } /* * draw the given platch: */ draw_pl(app) struct pltch *app; { register struct pltch *pp; register int j; register char *bp; pp = app; for(j=0; jnsides; j++) { bp = pp->side[j].which; /* points to boundary line/curve/arc */ if( bp->flag ) continue; bp->flag++; switch( pp->side[j].what ) { case LINE: draw_line(bp); break; case CURVE: draw_crv(bp); break; case ARC: draw_arc(bp); break; } } } /* * get the address of the i th element of a list: */ char *get_i_th(start , ii) char *start; int ii; { register char *p; register int i; i=ii; p=start; while(i--) p=p->next; return(p); } /* * return a pointer to the last element of a list: * (only works because all structs have the "next" pointer in the first word) */ char *get_last(start) char *start; { register char *p; for(p=start; p->next!=0; p=p->next); return(p); } /* * locate the platch indicated by the 4 marks: */ char *get_pltch() { register char *p , *w , *pp; char *p1 , *p2 , *p3 , *p4; int j; draw_marks(); if( num_m < 4 ) { mesg("Need 4 Marks"); return(0); } if( num_pl<=0 ) { mesg("No Platches in Data Structure"); return(0); } p4 = (p3 = (p2 = (p1=mark.mark)->mark )->mark )->mark; for(p=pltch.nextpl; p!=0; p=p->nextpl) { for(j=0; jnsides; j++) { w = p->side[j].which; switch( p->side[j].what ) { case LINE: if( (pp=w->l1)!=p1 && pp!=p2 && pp!=p3 && pp!=p4 ) goto contin; if( (pp=w->l2)!=p1 && pp!=p2 && pp!=p3 && pp!=p4 ) goto contin; break; case CURVE: if( (pp=w->c1)!=p1 && pp!=p2 && pp!=p3 && pp!=p4 ) goto contin; if( (pp=w->c4)!=p1 && pp!=p2 && pp!=p3 && pp!=p4 ) goto contin; break; case ARC: if( (pp=w->a1)!=p1 && pp!=p2 && pp!=p3 && pp!=p4 ) goto contin; if( (pp=w->a2)!=p1 && pp!=p2 && pp!=p3 && pp!=p4 ) goto contin; break; } } /* if got this far, must have found the platch in question: */ return(p); contin:; } return(0); /* did not find any! */ } /* * highlight a single platch: */ hilite_pltch(pp , iflag) char *pp; { register char *p; p=pp; if( iflag ) { mseg(-HILITE); switch( flag.view ) { case VIEW1: mdim(OBJECT , 15); break; case VIEW2: mdim(STRIGHT , 15); break; case VIEW4: mdim(UPPERLEFT , 15); break; } return; } mseg(HILITE); switch( flag.view ) { case VIEW1: mdim(OBJECT , DIM); new_matrix(HILITE , xform); break; case VIEW2: mdim(STRIGHT , DIM); mmult(xform , &quarters[STRIGHT][0] , m1); new_matrix(HILITE , m1); break; case VIEW4: mdim(UPPERLEFT , DIM); mmult(xform , &quarters[UPPERRIGHT][0] , m1); new_matrix(HILITE , m1); break; } zero_flags(); draw_pl( p ); } /* * see if a given coordinate is specifying a command in a given menu: */ hit_menu(amp , hx , hy) struct menu *amp; int hx , hy; { register struct menu *mp; register int j; j=0; for(mp=amp; mp->menu_s!=0; mp++) { if( mp->ints==0 ) { j++; continue; /* this option turned off */ } if( hit_string(mp->menu_s , mp->mx , mp->my , mp->scale , hx , hy) ) return(j); j++; } return(-1); } /* * test to see if 2D cursor is over a point: * (return a pointer to it if it is, else return 0) */ char *hit_pt(ix , iy) { register struct vert *p; register int x , y; x=ix; y=iy; if( flag.proj ) proj_all(); /* may need to project the points to 2D first */ for(p=vert.nextv; p!=0; p=p->nextv) { if( abs(x - p->sx) > BOX ) continue; if( abs(y - p->sy) > BOX ) continue; return(p); } return(0); } /* * see if a given position lies within a given string: */ hit_string(as , ix , iy , scal , hx , hy) char *as; int ix , iy , scal , hx , hy; { register char *s; register int d , scl; scl = scal; scl=& 07; s=as; d = 9*(++scl); if( abs(hy-iy) > d ) return(0); d = 6*scl * count_char(s); return( ( abs(hx-ix) <= d ) ); } /* * initialize the program data: */ init() { register int twice , j; register char *now; register float *fp; float scl; float c , s; /* used for stereopairs */ float t , dt , t2 , t3; char *sbrk(); vert.nextv = pltch.nextpl = line.nextl = crv.nextc = arc.nexta = free.nextf = 0; /* set free list to be entire rest of memory: */ now=sbrk(0); now++; now=& ~1; /* word boundary */ brk(0157776); /* break to end */ free.nextf = now; now->nextf = 0; now->nbytes = 0157776 - now; flag.xyz = X; flag.view = VIEW1; num_m = 0; mark.mark = -1; /* nothing in mark list */ meg_setup(); dev_init(); /* init joystick & kb */ /* init the Overhauser and Bezier matrices (bug in cc40!): */ fp = &ohmat[0][0]; *fp++= -.5; *fp++= 1.5; *fp++= -1.5; *fp++= .5; *fp++= 1.; *fp++= -2.5; *fp++= 2.; *fp++= -.5; *fp++= -.5; *fp++=0.; *fp++= .5; *fp++=0.; *fp++= 0.; *fp++= 1.; *fp++= 0.; *fp= 0.; fp = &bzmat[0][0]; *fp++= -1.; *fp++= 3.; *fp++= -3.; *fp++= 1.; *fp++= 3.; *fp++= -6.; *fp++= 3.; *fp++= 0.; *fp++= -3.; *fp++= 3.; *fp++= 0.; *fp++= 0.; *fp++= 1.; *fp++= 0.; *fp++= 0.; *fp= 0.; /* init the mark seg */ mseg(MARKER); /* create the 2D cursor */ twice = BOX<<1; /* = length of one side */ mseg(CURSOR); mwindow(-2048+BOX , -2048+BOX , 2047-BOX , 2047-BOX); mcursor(CURSOR); mdash(CURSOR , DASH); mrplot2(-BOX,-BOX,3); mrplot2(twice , 0 , 2); mrplot2(0 , twice , 2); mrplot2(-twice , 0 , 2); mrplot2(0 , -twice , 2); /* draw the background */ mseg(BACKG); mplot2(-2048,-2048,3); mplot2(2047,-2048,2); mplot2(2047,2047,2); mplot2(-2048,2047,2); mplot2(-2048,-2048,2); mplot2(LEFT,BOTTOM,3); mplot2(RIGHT,BOTTOM,2); mplot2(RIGHT,-2048,3); mplot2(RIGHT,TOP,2); mmark(); ident( &xform[0][0] ); /* set global matrix to identity */ ident( &curs_xform[0][0] ); /* set the cursor transformation to identity */ /* generate the little cube to be used for marks: */ mseg( SMALLCUBE ); mblank( SMALLCUBE ); twice = CUBE<<1; /* length of one side */ mrplot3(-CUBE , -CUBE , -CUBE , 3); mrplot3(twice , 0 , 0 , 2); mrplot3(0 , twice , 0 , 2); mrplot3(-twice , 0 , 0 , 2); mrplot3(0 , -twice , 0 , 2); mrplot3(0 , 0 , twice , 2); mrplot3(twice , 0 , 0 , 2); mrplot3(0 , twice , 0 , 2); mrplot3(-twice , 0 , 0 , 2); mrplot3(0 , -twice , 0 , 2); mrplot3(0 , twice , 0 , 3); mrplot3(0 , 0 , -twice , 2); mrplot3(twice , 0 , 0 , 3); mrplot3(0 , 0 , twice , 2); mrplot3(0 , -twice , 0 , 3); mrplot3(0 , 0 , -twice , 2); mseg( TRACES ); mblank(TRACES); mmark(); flag.view = VIEW1; /* setup transformations for quarters of 4 views: */ scl = 0.5; for(j=LOWERLEFT; j<=STRIGHT; j++) ident( &quarters[j][0] ); quarters[UPPERLEFT][5] = quarters[UPPERLEFT][10] = quarters[LOWERRIGHT][0] = quarters[LOWERRIGHT][10] = 0.0; quarters[UPPERLEFT][6] = quarters[LOWERRIGHT][2] = 1.0; quarters[UPPERLEFT][9] = quarters[LOWERRIGHT][8] = -1.0; ident(m1); m1[0][0] = m1[1][1] = scl; /* matrix to scale down pictures */ m1[3][0] = 0.75*LEFT + 0.25*RIGHT; m1[3][1] = 0.75*BOTTOM + 0.25*TOP; mmult( &quarters[LOWERLEFT][0] , m1 , &quarters[LOWERLEFT][0] ); m1[3][1] = 0.25*BOTTOM + 0.75*TOP; mmult( &quarters[UPPERLEFT][0] , m1 , &quarters[UPPERLEFT][0] ); m1[3][0] = 0.25*LEFT + 0.75*RIGHT; mmult( &quarters[UPPERRIGHT][0] , m1 , &quarters[UPPERRIGHT][0] ); m1[3][1] = 0.75*BOTTOM + 0.25*TOP; mmult( &quarters[LOWERRIGHT][0] , m1 , &quarters[LOWERRIGHT][0] ); c = COS5; s = SIN5; /* use 5 degrees */ m1[3][0] = 0.75*LEFT + 0.25*RIGHT; m1[3][1] = 0.0; ident( m2 ); m2[0][0] = m2[2][2] = c; m2[0][2] = -( m2[2][0] = s ); mmult( m2 , m1 , m1 ); mmult( &quarters[STLEFT][0] , m1 , &quarters[STLEFT][0] ); ident(m1); m1[0][0] = m1[1][1] = scl; /* matrix to scale down pictures */ m1[3][0] = 0.25*LEFT + 0.75*RIGHT; m2[2][0] = -( m2[0][2] = s ); mmult(m2 , m1 , m1); mmult( &quarters[STRIGHT][0] , m1 , &quarters[STRIGHT][0] ); /* setup b0 , b1 , db0dt , db1dt arrays: */ t=0.0; dt = 1./NFILL; for(j=0; j<=NFILL; j++) { t3 = t*(t2=t*t); b0[j] = 1. - (b1[j]= 3.*t2 - 2.*t3); db0dt[j] = -( db1dt[j]= 6.*t*(1.-t) ); t=+ dt; } } /* * determine if the given bounding curve is a line: * can happen one of 2 ways: * (1) really is a line * (2) is a curve with colinear pts */ is_line(what , which) char *which; { register struct vert *vp , *vp1 , **p; int j , xydone , xzdone , infxy , infxz; float xy , xz , n , d , fabs(); if( what==LINE ) return(1); /* that was easy */ if( what==ARC ) return(0); /* ditto */ /* see if 4 pts of curve are colinear: */ p = &which->c1; vp1 = *p++; /* points to pt #1 */ infxy = infxz = xydone = xzdone = 0; /* clear flags */ for(j=1; j<=3; j++) { vp = *p++; /* points to current point */ if( vp==vp1 ) continue; /* possible to have 2 pts the same */ n = vp->x - vp1->x; d = vp->y - vp1->y; if( fabs(d) == 0.0 ) { /* since were using integers, d would be exactly 0.0 */ if( xydone ) { if( infxy==0 ) return(0); } else { xydone++; infxy++; } } else { if( xydone==0 ) { xy = n/d; xydone++; } else { if( fabs(xy - (n/d)) > LINETOL ) return(0); } } d = vp->z - vp1->z; if( fabs(d) == 0.0 ) { /* since were using integers, d would be exactly 0.0 */ if( xzdone ) { if( infxz==0 ) return(0); } else { xzdone++; infxz++; } } else { if( xzdone==0 ) { xz = n/d; xzdone++; } else { if( fabs(xz - (n/d)) > LINETOL ) return(0); } } } return(1); /* if got to here, they all are colinear (I think) */ } /* * i_th : returns the ordinal number of the address in the * given list. The first element (the one pointed to by * start) is element 0. */ i_th(start , iaddr) char *start , *iaddr; { register char *p , *addr; register int j; addr = iaddr; j=0; for(p=start; p!=0; p=p->next) { if( p==addr ) return(j); j++; } return(-1); /* failure */ } /* * exchange two memory locations: */ ixchg(mem1 , mem2) int *mem1 , *mem2; { register int tmp; tmp = *mem2; *mem2 = *mem1; *mem1 = tmp; } /* * loop till have found a menu hit. * return that hit #. * a non-zero flag means return on any button strike. */ loop(amp , iflag) struct menu *amp; { register struct menu *mp; register int i; int ix , iy; mp=amp; if( nargs()==1 ) iflag = 0; for(EVER) { mdim(CURSOR , 12); while( (i=mbutton()) == 0 ); /* wait for a button strike */ mmouse(&ix , &iy); if( (i=hit_menu(mp,ix,iy)) >= 0) { mdim(CURSOR , 15); return(i); } if( iflag ) { mdim(CURSOR , 15); return( -1 ); } } } /* * fill the matrix "xform" to reflect the current transformation: */ make_xform() { register float *fp; fp = &xform[0][0]; *fp++ = cosy*cosz*sclxyz; *fp++ = cosy*sinz*sclxyz; *fp++ = -siny*sclxyz; *fp++ = 0.0; *fp++ = (sinx*siny*cosz - cosx*sinz) * sclxyz; *fp++ = (sinx*siny*sinz + cosx*cosz) * sclxyz; *fp++ = sinx*cosy*sclxyz; *fp++ = 0.0; *fp++ = (cosx*siny*cosz + sinx*sinz) * sclxyz; *fp++ = (cosx*siny*sinz - sinx*cosz) * sclxyz; *fp++ = cosx*cosy*sclxyz; *fp++ = 0.0; *fp++ = *fp++ = *fp++ = 0.0; *fp = 1.0; fp = &m1[3][0]; ident( m1 ); *fp++ = tranx; *fp++ = trany; *fp = tranz; mmult(m1 , xform , xform); } /* * mark the given point: */ markit(pp) char *pp; { register char *p , *last; if( (p=pp)->mark ) { mesg("Already Marked!"); return; } for(last= &mark; last->mark!= -1; last=last->mark); last->mark = p; p->mark = -1; draw_marks(); } /* * remove all marks: */ all_un_mark() { register char *p; for(p=vert.nextv; p!=0; p=p->nextv) p->mark = 0; mark.mark = -1; draw_marks(); } /* * remove the given point from the mark list: */ un_markit(pp) char *pp; { register char *p , *mp; if( (p=pp)->mark == 0 ) { mesg("Not Marked"); return; } for(mp= &mark; mp->mark!=p; mp=mp->mark); /* mp now points to structure before the one destroying: */ mp->mark = p->mark; p->mark = 0; draw_marks(); } /* * display a message for one second: */ mesg(str) char *str; { mseg( MESG ); mplot2(MESGX , MESGY , 3); burp(); mstring(MESGSCL , str); sleep(2); mseg( -MESG ); } /* * move a pt: */ move() { register int j; int x , y , z; /* save the given point's original values */ x = point->x; y = point->y; z = point->z; plot_menu( &menu2 ); for(EVER) { switch( (j=loop(&menu2)) ) { case EXIT: point->x = x_3d; point->y = y_3d; point->z = z_3d; project( point ); /* change it to 2D */ draw_all(); draw_marks(); flag.write++; /* set written flag */ mseg( -MOVER ); return; case ABORT: point->x = x; point->y = y; point->z = z; project( point ); mappend(OBJECT); mreset(); update_curs(); mseg( -MOVER ); return; case XM: flag.xyz = X; move_pt(); break; case YM: flag.xyz = Y; move_pt(); break; case ZM: flag.xyz = Z; move_pt(); break; case XYM: flag.xyz = XY; move_pt(); break; case XZM: flag.xyz = XZ; move_pt(); break; case YZM: flag.xyz = YZ; move_pt(); break; } } } /* * do the dirty work in moving a point: */ move_pt() { register int dx , dy; int idx , idy; mblank(CURSOR); mappend( OBJECT ); mmark(); mdim(OBJECT , DIM); while( mbutton() ) { mdirections(&idx , &idy); /* read joystick byte and get js directions */ dx = idx; dy = idy; switch( flag.xyz ) { case X: point->x = (x_3d=+ dx); break; case Y: point->y = (y_3d=+ dy); break; case Z: point->z = (z_3d=+ dx-dy); break; case XY: point->x = (x_3d=+ dx); point->y = (y_3d=+ dy); break; case XZ: point->x = (x_3d=+ dx); point->z = (z_3d=+ dy); break; case YZ: point->y = (y_3d=+ dy); point->z = (z_3d=+ dx); break; } mreset(); mintsty(15); draw_only(point); /* translate the 3D cursor: */ update_curs(); } /* make 2D cursor re-appear */ mblank(-CURSOR); } /* * change the color of a platch: */ new_color( p ) struct pltch *p; { plot_menu( &menu6 ); mseg(MESG); mplot2(MESGX , MESGY , 3); mstring(MESGSCL , "Old color was: "); mstring(MESGSCL , menu6[p->color].menu_s ); burp(); return( loop(&menu6) ); } /* * change the parameters of a platch: */ parameters(pp) struct pltch *pp; { register struct pltch *p; register int j; p=pp; hilite_pltch(p , 0); plot_menu( &menu5 ); for(;;) { switch( (j=loop(&menu5)) ) { case EXIT: hilite_pltch(p , 1); return; case COLOR: p->color = new_color(p); mseg(-MESG); plot_menu(&menu5); continue; case TRANSPARENCY: continue; } } } /* * draw a line: */ plot_line(x1,y1,z1 , x2,y2,z2) { mplot3(x1,y1,z1,3); mplot3(x2,y2,z2,2); } /* * draw the given menu: */ plot_menu(amp) struct menu *amp; { register struct menu *mp; register int i; mseg(MENU); for(mp=amp; mp->menu_s!=0; mp++) { if( (i=mp->ints)==0 ) continue; mintsty(i); center_string(mp->menu_s , mp->mx , mp->my , mp->scale); } burp(); } /* * plot points at the given vertices: */ point_plot( arg1 ) int *arg1; { register int n; register int *p , *vp; if( (n=nargs()) <= 0 ) return; p = &arg1; while( n-- ) { vp = *p; mplot3(vp->x , vp->y , vp->z , 5); p++; } } /* * list the current state of the data structure: */ print() { register char *p; register int i , j; printf("\n\7\7"); printf("\n\n\t%d points:",num_v); for(p=vert.nextv; p!=0; p=p->nextv) printf("\n%o\t%d\t%d\t%d", p , p->x , p->y , p->z); printf("\n\n\t%d platches:", num_pl); for(p=pltch.nextpl; p!=0; p=p->nextpl) { i = p->nsides; printf("\n%o\t",p); for(j=0; jside[j].what ) { case LINE: printf("L"); break; case CURVE: printf("C"); break; case ARC: printf("A"); break; } printf("\t%o\t", p->side[j].which); } } printf("\n\n\t%d lines:", num_l); for(p=line.nextl; p!=0; p=p->nextl) printf("\n%o\t%o\t%o", p , p->l1 , p->l2); printf("\n\n\t%d curves:",num_c); for(p=crv.nextc; p!=0; p=p->nextc) { printf("\n%o\t", p); switch( p->whatc ) { case OH: printf("OH"); break; case BZ: printf("BZ"); break; } printf("\t%o\t%o\t%o\t%o", p->c1 , p->c2 , p->c3 , p->c4); } printf("\n\n\t%d arcs:",num_a); for(p=arc.nexta; p!=0; p=p->nexta) printf("\n%o\t%o\t%o\t%o", p , p->a1 , p->a2 , p->c); printf("\n\n\tFree List:"); for(p=free.nextf; p!=0; p=p->nextf) printf("\n%o\t%d", p , p->nbytes); printf("\n\7\7\7"); mesg("Done"); } /* * convert a 3D point into a 2D point depending on xform[][] : */ project( pp ) struct vert *pp; { register struct vert *p; register float *fp , *mp; float xyz[4]; make_xform(); switch( flag.view ) { case VIEW1: mp = &xform[0][0]; break; case VIEW2: mmult(xform , &quarters[STRIGHT][0] , m1); mp = &m1[0][0]; break; case VIEW4: mmult(xform , &quarters[UPPERRIGHT][0] , m1); mp = &m1[0][0]; break; } p = pp; fp = &xyz[0]; *fp++ = p->x; *fp++ = p->y; *fp++ = p->z; *fp = 1.0; vmult(xyz , mp , xyz); fp = &xyz[0]; p->sx = *fp++; p->sy = *fp; } /* * convert all 3D points to 2D: */ proj_all() { register struct vert *p; for(p=vert.nextv; p!=0; p=p->nextv) project( p ); flag.proj = 0; } /* * change the global scale factor: */ scl_xform( s ) float s; { sclxyz=* s; } /* * fork off a shading job: */ char shprt[] { "Job 0000 Sent" }; char tmpname[] { "/tmp/eda" }; shader() { int di , dj; register int i , j , k; char c; char *p; float xyz[4] , sqrt() , cosang; int buf[18] , level; /* find a unique filename */ for(c='a'; c<='z'; c++) { tmpname[7] = c; if( stat(tmpname , buf) < 0 ) /* an unused name found */ break; if( c=='z' ) { /* no unused names found */ mesg("Cannot Make a Temporary File"); return; } } close( iobuf[0] ); /* want to re-use the iobuf */ if( fcreat(tmpname , iobuf) < 0 ) { printf("\"\n Cannot create %s\7\7",tmpname); mesg("Cannot Create Temp File"); return; } /* fill the platches: */ mseg( MESG ); mplot2(MESGX , MESGY , 3); mstring(MESGSCL , "Writing Data File . . ."); burp(); for(p=pltch.nextpl; p!=0; p=p->nextpl) { di = dj = 1; /* normal increment for i and j */ fill_traces(p , 1); /* get points and surface normals */ /* short-circuit if straight edges: */ if( is_line(p->side[0].what,p->side[0].which) && is_line(p->side[2].what,p->side[2].which) ) di = NFILL; if( is_line(p->side[1].what,p->side[1].which) && is_line(p->side[3].what,p->side[3].which) ) dj = NFILL; for(i=0; i<=NFILL; i=+ di) { for(j=0; j<=NFILL; j=+ dj) { xyz[3] = 1.0; for(k=0; k<3; k++) xyz[k] = fillin[i][j].val[k]; vmult(xyz , xform , xyz); fillin[i][j].xfs = xyz[0]; fillin[i][j].yfs = xyz[1]; fillin[i][j].zfs = xyz[2]; xyz[0] = fillin[i][j].nx; xyz[1] = fillin[i][j].ny; xyz[2] = fillin[i][j].nz; xyz[3] = 0.0; vmult(xyz , xform , xyz); /* dot this with (0,0,1) */ cosang = xyz[2]/sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1] + xyz[2]*xyz[2]); level = 29.*cosang*cosang + 0.5; /* shade # (0-29) */ fillin[i][j].nx = 32*p->color + level + 1; /* hide color in here */ } } /* send them: */ for(i=0; i=4; j--) { shprt[j] = '0' + pid%10; pid=/ 10; } mesg( shprt ); mesg( shprt ); } } /* * send the x, y, z, and color for the given point: */ shsend( pp ) char *pp; { register char *p; register int x , y; x = (p=pp)->xfs; y = p->yfs; x=>> 3; x=+ 256; /* change (-2048,2047) to (0,511) */ y=>> 3; y=+ 256; putw(x , iobuf); putw(y , iobuf); putw(p->zfs , iobuf); putw(p->nx , iobuf); /* color */ } /* * update the values of tranx, trany, and tranz: */ tran_xform(axis) { register int l; l = TRAN; ident( m1 ); if( axis < 0 ) { l = -TRAN; axis = -axis; } switch( axis ) { case X: tranx=+ l; break; case Y: trany=+ l; break; case Z: tranz=+ l; break; } } /* * re-draw the 3D cursor somewhere else: */ update_curs() { register struct vert *p; register float *fp; register int j; p=point; fp = &curs_xform[3][0]; ident( curs_xform ); *fp++ = x_3d = p->x; *fp++ = y_3d = p->y; *fp = z_3d = p->z; mmult(curs_xform , xform , m1); switch( flag.view ) { case VIEW1: new_matrix(CURS3D , m1); break; case VIEW2: mmult(m1 , &quarters[STLEFT][0] , m2); new_matrix(LCURS3D , m2); mmult(m1 , &quarters[STRIGHT][0] , m2); new_matrix(RCURS3D , m2); break; case VIEW4: mmult(m1 , &quarters[UPPERRIGHT][0] , m1); new_matrix(CURS3D , m1); break; } } /* * wait for the last job spun off: */ waitez() { register int id; int status; do { id = wait( &status ); } while( id>0 && id!=pid ); } /* * set flags to zero: */ zero_flags() { register char *p; for(p=vert.nextv; p!=0; p=p->nextv) p->flag=0; for(p=pltch.nextpl; p!=0; p=p->nextpl) p->flag=0; for(p=line.nextl; p!=0; p=p->nextl) p->flag=0; for(p=crv.nextc; p!=0; p=p->nextc) p->flag=0; for(p=arc.nexta; p!=0; p=p->nexta) p->flag=0; } x(CURS3D , m1); break; } } /* * wait for the last job spun off: */ waitez() { register int id; int status; do { id = wait( &status ); } while( id>0 && id!=pid ); } /* * set flags to zero: */ zero_flags() { register char *p; for(p=vert.nextv; p!=0; p=p->nextv) p->flag=0; for(p=pltch.nextp); p++; } } /* * list the current state of the data structure: */ print() { register char *p; register int i , j; printf("\n\7\7"); printf("\n\n\t%d points:",num_v); for(p=vert.nextv; p!=0; p=p->nextv) printf("\n%o\t%d\t%d\t%d", p , p->x , p->y , p->z); printf("\n\n\t%d platches:", num_pl); for(p=pltch.nextpl; p!=0; p=p->nextpl) { i = p->nsides; printf("\n%o\t",p); for(j=0; jside[j].what ) { case LINE: printf("L"); break; case CURVE: printf("C"); break; case ARC: printf("A"); break; } printf("\t%o\t", p->side[j].which); } } printf("\n\n\t%d lines:", num_l); for(p=line.nextl; p!=0; p=p->nextl) printf("\n%o\t%o\t%o", p , p->l1 , p->l2); printf("\n\n\t%d curves:",num_c); for(p=crv.nextc; p!=0; p=p->nextc) { printf("\n%o\t", p); switch( p->whatc ) { case OH: printf("OH"); break; case BZ: printf("BZ"); break; } printf("\t%o\t%o\t%o\t%o", p->c1 , p->c2 , p->c3 , p->c4); } printf("\n\n\t%d arcs:",num_a); for(p=arc.nexta; p!=0; p=p->nexta) printf("\n%o\t%o\t%o\t%o", p , p->a1 , p->a2 , p->c); printf("\n\n\tFree List:"); for(p=free.nextf; p!=0; p=p->nextf) printf("\n%o\t%d", p , p->nbytes); printf("\n\7\7\7"); mesg("Done"); } /* * convert a 3D point into a 2D point depending on xform[][] : */ project( pp ) struct vert *pp; { register struct vert *p; register float *fp , *mp; float xyz[4]; make_xform(); switch( flag.view ) { case VIEW1: mp = &xform[0][0]; break; case VIEW2: mmult(xform , &quarters[STRIGHT][0] , m1); mp = &m1[0][0]; break; case VIEW4: mmult(xform , &quarters[UPPERRIGHT][0] , m1); mp = &m1[0][0]; break; } p = pp; fp = &xyz[0]; *fp++ = p->x; *fp++ = p->y; *fp++ = p->z; *fp = 1.0; vmult(xyz , mp , xyz); fp = &xyz[0]; p->sx = *fp++; p->sy = *fp; } /* * convert all 3D points to 2D: */ proj_all() { register struct vert *p; for(p=vert.nextv; p!=0; p=p->nextv) project( p ); flag.proj = 0; } /* * change the global scale factor: */ scl_xform( s ) float s; { sclxyz=* s; } /* * fork off a shading job: */ char shprt[] { "Job 0000 Sent" }; char tmpname[] { "/tmp/eda" }; shader() { int di , dj; register int i , j , k; char c; char *p; float xyz[4] , sqrt() , cosang; int buf[18]; /* find a unique filename */ for(c='a'; c<='z'; c++) { tmpname[7] = c; if( stat(tmpname , buf) < 0 ) /* an unused name found */ break; if( c=='z' ) { /* no unused names found */ mesg("Cannot Make a Temporary File"); return; } } close( iobuf[0] ); /* want to re-use the iobuf */ if( fcreat(tmpname , iobuf) < 0 ) { printf("\"\n Cannot create %s\7\7",tmpname); mesg("Cannot Create Temp File"); return; } /* fill the platches: */ mseg( MESG ); mplot2(MESGX , MESGY , 3); mstring(MESGSCL , "Writing Data File . . ."); burp(); for(p=pltch.nextpl; p!=0; p=p->nextpl) { di = dj = 1; /* normal increment for i and j */ fill_traces(p , 1); /* get points and surface normals */ /* short-circuit if straight edges: */ if( is_line(p->side[0].what,p->side[0].which) && is_line(p->side[2].what,p->side[2].which) ) di = NFILL; if( is_line(p->side[1].what,p->side[1].which) && is_line(p->side[3].what,p->side[3].which) ) dj = NFILL; for(i=0; i<=NFILL; i=+ di) { for(j=0; j<=NFILL; j=+ dj) { xyz[3] = 1.0; for(k=0; k<3; k++) xyz[k] = fillin[i][j].val[k]; vmult(xyz , xform , xyz); fillin[i][j].xfs = xyz[0]; fillin[i][j].yfs = xyz[1]; fillin[i][j].zfs = xyz[2]; xyz[0] = fillin[i][j].nx; xyz[1] = fillin[i][j].ny; xyz[2] = fillin[i][j].nz; xyz[3] = 0.0; vmult(xyz , xform , xyz); /* dot this with (0,0,1) */ cosang = xyz[2]/sqrt(xyz[0]*xyz[0] + xyz[1]*xyz[1] + xyz[2]*xyz[2]); fillin[i][j].nx = 240*cosang*cosang; /* hide color in here */ } } /* send them: */ for(i=0; i=4; j--) { shprt[j] = '0' + pid%10; pid=/ 10; } mesg( shprt ); mesg( shprt ); } } /* * send the x, y, z, and color for the given point: */ shsend( pp ) char *pp; { register char *p; register int x , y; x = (p=pp)->xfs; y = p->yfs; x=>> 3; x=+ 256; /* change (-2048,2047) to (0,511) */ y=>> 3; y=+ 256; putw(x , iobuf); putw(y , iobuf); putw(p->zfs , iobuf); putw(p->nx , iobuf); } /* * update the values of tranx, trany, and tranz: */ tran_xform(axis) { register int l; l = TRAN; ident( m1 ); if( axis < 0 ) { l = -TRAN; axis = -axis; } switch( axis ) { case X: tranx=+ l; break; case Y: trany=+ l; break; case Z: tranz=+ l; break; } } /* * re-draw the 3D cursor somewhere else: */ update_curs() { register struct vert *p; register float *fp; register int j; p=point; fp = &curs_xform[3][0]; ident( curs_xform ); *fp++ = x_3d = p->x; *fp++ = y_3d = p->y; *fp = z_3d = p->z; mmult(curs_xform , xform , m1); switch( flag.view ) { case VIEW1: new_matrix(CURS3D , m1); break; case VIEW2: mmult(m1 , &quarters[STLEFT][0] , m2); new_matrix(LCURS3D , m2); mmult(m1 , &quarters[STRIGHT][0] , m2); new_matrix(RCURS3D , m2); break; case VIEW4: mmult(m1 , &quarters[UPPERRIGHT][0] , m1); new_matrix(CURS3D , m1); break; } } /* * wait for the last job spun off: */ waitez() { register int id; int status; do { id = wait( &status ); } while( id>0 && id!=pid ); } /* * set flags to zero: */ zero_flags() { register char *p; for(p=vert.nextv; p!=0; p=p->nextv) p->flag=0; for(p=pltch.nextpl; p!=0; p=p->nextpl) p->flag=0; for(p=line.nextl; p!=0; p=p->nextl) p->flag=0; for(p=crv.nextc; p!=0; p=p->nextc) p->flag=0; for(p=arc.nexta; p!=0; p=p->nexta) p->flag=0; } x(CURS3D , m1); break; } } /* * wait for the last job spun off: */ waitez() { register int id; int status; do { id = wait( &status ); } while( id>0 && id!=pid ); } /* * set flags to zero: */ zero_flags() { register char *p; for(p=vert.nextv; p!=0; p=p->nextv) p->flag=0; for(p=pltch.nextpl; p!=0; p=p->nextpl) p->flag=0; for(p=line.nextl; p!=0; p=p->nextl) p->flag=0; for(p=crv.nextc; p!=0; p=p->nextc) p->flag=0; .ʫA Aʫ}O*A  E@8B0,  0 ; w7 *9L}s+ _:CV ,Ep   VAp,ݩ(Ep   ,A ݩ( Ep h  * %pJ D %%p  %%p %%p %%p %%TUpx r %%TUUUpN H %%pUU$  %%p@ %%@p %%p  %@%qpq| v %2JRE AS FOLLOWS: /FORMAT FORMAT DISK PACK PRIOR TO OPERATION. OUTPUT DEV MUST BE RK OR RP. /BOOT:DEV BOOTSTRAP FROM SPECIFIED DEVICE. DEV MAY BE "DF" (RF11), "DK" (RK11), "DC" (RC11), "DT" (DECTAPE), "MT" (MAGTAPE), OR "DP" (RP03 DISK). /DATE:01-JAN-70 USED IN WRITING MAGTAPE LABEL (OPTIONAL). /FIND ON INPUT FROM MAGTAPE, PERFORM A SEARCH FOR THE S 13.KLB#14. KLB#15. KLB#16.zKT.fKWL.`KWP.8LATST.HLP.MM.?MM. _MM.MM.MM. MM.MM.@MP#1.BMP#2.DMP#3.FMP#4. HMP#5.JMP#6.LMP#7. NMP#8. PMP#9.RMP#10.TMP#11.VMP#12.XMP#13.ZMP#14.\MP#15.^MP#16.MROM.MX#1.MX#2.MX#3.MX#4.MX#5. MX#6.@OST45.hPC. PR6P#1. PR6P#2. PR6P#3. PR6P#4.PR6P#5.PR6P#6.PR6P#7.PR6P#8.PR6R#1.PR6R#2.-PR6R#3.PR6R#4.PR6R#5.PR6R#6.PR6R#7.PR6R#8. RC. 0RF.RK.RP." Aݩ(Ep,   AJ".A J wA47 * w9L +_gD.AJ  A}A*Zjn,ݩE@8  jhv}*vA  Ah.zf\f\\%qb\%%q82%%q%%q%%q%?%q%%qf`%%q<6%%q %%q %%q %%q %  %H8p8R L %2%@,p( " %%p %%ߗp  %+%<p  %+%<ԗp z %%pV P %%p, & %%p  %%p  %%p  %%p ~ %CPECIFIED FILE. ON OUTPUT TO MAGTAPE, SKIP TO END OF DATA. /HELP TYPE THIS DOCUMENT. /NOLABEL ON DISK TO DECTAPE DUMPS, PREVENTS THE LABEL RECORD FROM BEING WRITTEN. /NUMBER:N N IS THE NUMBER OF 1K TRACKS TO DUMP OR RESTORE. /PLATTERS:N FOR RF11 OR RC11 ONLY, N IS THE NUMBER OF DISK PLATTERS TO DUMP OR RESTORE. /RWIND REWIND THE MAGTAPE BEFORE USE. /SKIr . w w &w $\\&&\ w.St`}s+@+@9L@.;@E@8@J@@{@.@@Q@,0z@A@ON@.}@_@Ϋ(d@@ @.(St`hw(F'@((7 St`7 k.ON@QΫ(d9L}s+"_N 0Z. %pB<%%p%%p%%p%%p%%ppj%%pF@%%p%%p %%p  %?%p %%pt n %]%TUqj d%%TUUUq@:%%qUU%%q@ %%@q %%q%@%qqqnh%2%H8q8D>%2%@,q %%q %%q%+%<q1%pZ T %%p0 * %%p %%q%%q%%q%%q^X%%q4.%%q %%q%%q%%q%E@8  00*; w ; w<7 .9L}s+ _; wN7 *9L+ _E@8`h7 , h } 9L}s+r7 V._; w 9L+,_}  E@8 . (08@HPX`hpx (08@HPX`hpx (08@HPXhpx (08@HPX`hpx (08@HPX`hpx (08@HPX`hpx (08@HPX`hpx (0 %pJ D %%p  %%p %%p %%p %%TUpx r %%TUUUpN H %%pUU$  %%p@ %%@p %%p  %@%qpq| v %2J%+%<qrl%%qHB%%q%%q%%Wq%%Wq%%Wqv p%%WqLF%%Wq"%%Wq%%@247p %%?p AJ wΫ(d 7 N*9L}s+_{ w 7 .Ϋ(d 9L +_}A8.f\f\\\y}w@ \.3gSj8v@}s+@+@.9L@E@8@@۩@ݩ@.{@@Q@,0z@A@ON@.@}@_@ʫ@Ϋ(d@.@ @DISK ERROR--REQUEST KILLED. DISK ERROR ON UNIT --REQUEST KILLED. THE REEL LABEL INDICATES THAT THE REST OF THE TAPE WAS NOT DUMPED. TYPE K TO KILL REQUEST AT THIS POINT, ANYTHING ELSE TO PROCEED IN FACE OF DANGER: LABEL INDICATES THAT THE TAPE IS OUT OF SEQUENCE. TYPE P TO PROCEED, M TO MOUNT ANOTHER REEL, OR K TO KILL REQUEST: MOUNT TAPE ON DT, TYPE RETURN TO CONTINUE WHEN READY.TOO FEW DECTAPE UNITS WERE SPECIFIED. REQUEST KILLED. PREMATURE END-OF-FILE, REQUEST KILLED\z8@HPX`hpx (08@HPX`hpx0@HPX`hpx (08 (08`hp 0p (08@PX`hx@PXw,y %H8p8R L %2%@,p( " %%p %%ߗp  %+%<p  %+%<ԗp z %%pV P %%p, & %%p  %%p  %%p  %%p ~ %C@8@(3gShw(F"7 3gS.ON@QAݩE@8R".* "  Ϋ(d.9L *7 7 n,j8v _۩9L}s+vBNZ._@8 N ZA/T&bD, w&b A wDcb7 ,9L+ _%TUqj d%%TUUUq@:%%qUU%%q@ %%@q %%q%@%qqqnh%2%H8q8D>%2%@,q %%q %%q%+%<q1 . TAPE FULL, TYPE M TO MOUNT ANOTHER REEL AND CONTINUE, ANYTHING ELSE TO ABORT REQUEST: SELECT ERROR ON MT: MAGTAPE WRITE PROTECT ERROR. FATAL MAGTAPE ERROR. SPECIFIED DEVICE DOES NOT EXIST. REACHED END-OF-DATA ON SKIP, OPERATION KILLED. END-OF-FILE DURING READ, TYPEMAGTAPE FILE NAME DOES NOT MATCH SPECIFIED NAME. CAN'T FIND SPECIFIED FILE ON TAPE. NO OUTPUT FILE NAME SPECIFIED. MAGTAPE RECORD TOO LONG FOR BUFFER. VERIFICATION ERROR--COPY IS BAD. /VERIFY IS NOT  0<00F`07    ߋ ߋTE PROGRAM #2%:DATE: %RESTART: %INV DATE%  xХ ȥ =  6z6weeeeeeeeeee 0= c F e Dww w 0  ` ` ee0`  PW )|x0Pnh~ t .:Aʫ8v7 ,Ϋ(d 9L j8v_۩7 .9L}s+ _@8nJ*A ʫn{&D , w& { wD9L*7 f\f\\+ _}q.N~Epx@yke@9L@.;@E@8@Ep@ݩ@@Q@.@, %%p2n h%%pF @%%p %%#p %%4p %%%2%@,q %%q %%q%+%<q1%p:4%%p %%Wp%%Wp%%Wp %%Wphb%%Wp>8%%Wp%%p%%p%%p%%plf%  lΫ(d"7 ,Ϋ(d 9L yke_Ϋ(d c*Ϋ(d Ϋ(dΫ(d9L$7 2*px  _Ϋ(d29Lf ,7 V \.yke K@Q_Ϋ(dVΫ(d\n(D^`7 .Ϋ(d^ Ϋ(d`9LpxCd*_Of } Epor%p:4%%p %%Wp%%Wp%%Wp %%Wphb%%Wp>8%%Wp%%p%%p%%p%%plf% %pJ D %%p  %%p %%p %%p %%TUpx r %%TUUUpN H %%pUU$  %%p@ %%@p %%p  %@%qpq| v %2J\&&\a" \\.w w w}$~#. ~ ; Of.\ ,} K@Q K@Q K@Q "K@Q&\\\&&\K.!"df@Lq,@sN@.}s+@w@ON@+@s@.쨀p@9L@;@;P@E@8@n.Ep@J@vp@@ݩ@b.ݩ@ݩ(@:@{@@k.Ԫp@@Q@@8@p@,0z@.A@O 0<00F`07    ߋ ߋTE PROGRAM #2%:DATE: %RESTART: %INV DATE%  xХ ȥ =  6z6weeeeeeeeeee 0= c F e Dww w 0  ` ` ee0`  PW )|x0Pnh~ t .: %pB<%%p%%p%%p%%p%%ppj%%pF@%%p%%p %%p  %?%p %%pt n %]3\\!$\`.|`   z,`zPT;_z +L9w .a7 z>2; w ;_({2z+}sL9_ +L9,?7 z7 w ;_ +}sL9.7  M(   @8E*%( V|zJAN@}@_@_@.p@P@Ϋ(d@Ϋ@y@@. @(`!"h@($df@( w(F"7 !".ON@QAݩE@8  ,s,  } Ϋ(d,9LLq,.$7 B.$_  Ep B@8.}A J @EpPZ %pJ D %%p  %%p %%p %%p %%TUpx r %%TUUUpN H %%pUU$  %%p@ %%@p %%p  %@%qpq| v %2J%p:4%%p %%Wp%%Wp%%Wp %%Wphb%%Wp>8%%Wp%%p%%p%%p%%plf%  _.|z7 $+L9w z ; _.z7 +}sL9   ,Z@8E_ +L9*'7 w ; w z;.zw ;  ;L,LD ݩpE n L.anL p , Z  Aݩ(c`,+.p  pvpP,p& ,&Ԫp  쨀pP @ ~&,&Ԫp  쨀pP @&],&Ԫp  쨀pP @7 *{ 9L sN @_202,; df@0 ; 2;@40 b* %%p2n h%%pF @%%p %%#p %%4p %%.;2 6 pEp(0. 0%qb\%%q82%%q%%q%%q%?%q%%qf`%%q<6%%q %%q %%q %%q %  0<00F`07    ߋ ߋTE PROGRAM #2%:DATE: %RESTART: %INV DATE%  xХ ȥ =  6z6weeeeeeeeeee 0= c F e Dww w 0  ` ` ee0`  PW )|x0Pnh~ t .:;@QNO, y7 "F(wh y(@ @@_.Z@}@芓@NO@A@0z,.@@@Q@@ݩ@.@J@pE@@8E@P;@;.@L9@+@+}s y.d~  \&&~\n&h^pzEh^\\H.` rJ\  Ep8@. @  EpuHP, P  Xd",E@8  d "f@*;@  v .Epݩ    "*E@8   "BB*  %pZ T %%p0 * %%p %%q%%q%%q%%q^X%%q4.%%q %%q%%q%%q%%TUqj d%%TUUUq@:%%qUU%%q@ %%@q %%q%@%qqqnh%2%H8q8D>%2%@,q %%q %%q%+%<q1\\`r".AB r ;_*PBr+L9 @yΫ 4S _J,7  7 Jvj8L9Dw  ;.:D&w ;  @8*&D_+}s L9 @yΫ4S,D7 _Jvj8L9_+L9.[7 J7 "@yΫ4S_  {B9LVB7 47 5,+B _9L}s+4_B*; w ; B w_47 FX,9L+ 4_F9L47 (d,}s+4 _;P @ w( ,*;P @ w, ;P @04* w0;P @ w4 ;P8<E, @ w8;P @ w<3  %H8p8R L %2%@,p( " %%p %%ߗp  %+%<p  %+%<ԗp z %%pV P %%p, & %%p  %%p  %%p  %%p ~ %C %qb\%%q82%%q%%q%%q%?%q%%qf`%%q<6%%q %%q %%q %%q % r vj8L9,7 r+Dw J ; &w *DJ&)J; @8 l_,Jl|+}sL9x@yΫ 4S _r,7 x7 rfQvj8L9_+ L9X@yΫ.7 XN {4S_B vj8L9Dw *7 BD>r;@  &w r;,fr@&r0::0@8  @D<*;P @ w@ { wD47 C,9L+ 4_{>&BB7 B*B9L+ B_;B87 \. df@9LON @_Ϋ(dJ^4DB B.^9Ls 4DB @ \7 , @ _ ; w;芼lD*D w;  w;_x%TUqj d%%TUUUq@:%%qUU%%q@ %%@q %%q%@%qqqnh%2%H8q8D>%2%@,q %%q %%q%+%<q1%pZ T %%p0 * %%p %%q%%q%%q%%q^X%%q4.%%q %%q%%q%%q%<_+}sL9.::0<7  d@yΫ4S_B vj8L9,67 B  @8E4*4:<0;  &w .<0&=;~ w P;zw *~z+P;}   ***1:r ; Jr;,4:rJrBJ;h ~^* @ w{ w;P <, @ w ;P @ w$*;P @ w ;P @* w;P @ w ;PE ", @ w;P @ w"_&F*{ w& F @8:P.(DB7 1, w({ wD 9L+B  4,_Ϋ(d  %pJ D %%p  %%p %%p %%p %%TUpx r %%TUUUpN H %%pUU$  %%p@ %%@p %%p  %@%qpq| v %2J%+%<qrl%%qHB%%q%%q%%Wq%%Wq%%Wqv p%%WqLF%%Wq"%%Wq%%@247p %%?p P;Zz*BJh~Zz;P;  pE,Tt  pE.TtTt Dw ;~0w , TtD~0TP;z,w P; z,vz,zt @8E4l_ +}s,4l7 ^L9b@yΫ4S_ rvj8,~b7 rLL9 J  Ϋ(d9Ldf@7 @J, @_  ;@1\.  Epݩ (.  ({]BB7 ,.B9L+ B_;P w,0(N0RH,N;P w0 R Ϋ(dH9Lq 8DBNR7 F.s D BNR_FpPh j %%p2n h%%pF @%%p %%#p %%4p %%p4lr芓A hPp.24lrh,/^ZP:@8 L J{.r^ZLJ;B{02;@QNO*B02}Zy7 "F(wh}Zy(@@8.@ @@@yΫ@P@_.M@_@}@芓@4S@NO.9@A@0z,@p@@8@@Q.@@{,@8Ϋ@yh Ϋ(dj9Lw2$bLB7 7 -.LB_9L}s+_~D*; w ; D wa( ,*;P w( w  ;P w,0* w;P w0 w ;P48, w4 w;P w8 w<@*;P w< w ;P w@R"D&F\. w"; wD w %%p2n h%%pF @%%p %%#p %%4p %%DJPV\bhntzw "(.4:@FLRX^djpv|I@:@@J.@pE@@8E@P;@;@L9.@+@+}s@vj8}Zy.EDw &w\\\\D\&,}JA &w .X\f\f &&;:  &w ;,:&`   @8E. }_+ L9 @yΫ4S.F7 & F@8(D.:P w( { wD9L.B7 7 /,+B _9L}s+_B(.;B w ;P @ w(m ,*;P @ w, ;P @04w* w0;P @ w4 ;P8<<, @ w8;P @ w<3  @D4*;P @ w@ { wD%+%<qrl%%qHB%%q%%q%%Wq%%Wq%%Wqv p%%WqLF%%Wq"%%Wq%%@247p %%?p %%p2n h%%pF @%%p %%#p %%4p %% : @8E.:!7 ,9L+ _Ϋ(d2,@4D .@9Ls 4D @ 1>7 7 * @ _ 9L}s+_$RD0*; w ; D wa^v*; @ w { wj b*;P @ w  ;P @ tB* w;P @ w ;P]~ , @ w$ %%p2n h%%pF @%%p %%#p %%4p %%%2%@,q %%q %%q%+%<q1w ,w @j\X0,D.^w w @QK @QK },!\f"*T@QK P;_S3gL9*$T7  I(dΫ(dΫ (dΫ".n  "  @8@8,pEHp ` 0pE*1H`0uH0@8 pE Bp`.H0)&0@@\A0@ULe&&\.+;@;P@E@8@.Ep@J@JP@c]@@:.@@ݩ@@+]@.7%@7@8@7p@:@{@Q.@@Q@@@8@p@a.,0z@-}@A@C@CP@_.ON@Of@Oi@S2@S4@.}@ʫ@ʫP@̫@`@@. @je;@(+ 5 n j 7 wC m̋  ss̸E@ w@  w@ ! 3 ^ :e%,e5% 7 7 7 7 M  "@ @ m7@ @ m@ @ 76 e0 % ; Y m    (5@)p %   B  Ü Ü 5/,%+%<qrl%%qHB%%q%%q%%Wq%%Wq%%Wqv p%%WqLF%%Wq"%%Wq%%@247p %%?pB`[(ݩA@8E X ݩA.XTPp`*_S3g*T`*7 ">L9(dΫ (dΫ@yΫ*T @8$   .$|@8*pE N p`**N`*n@8Ejݩ A,Wj ^|b^  @8@8,b-+hw(F/v( o"7 +2 s,ON@Q{ v Aݩ^(*E@8  ((<,Aݩ  E@8 <8r[,rA ݩ@8E@8HR(?* R  (S2.Vf(//' SEGMENT BLOCKS.'/&S2f-}7%0?4.BBB    Ee0 _ _ _ _ _ _ _ _ _ _  _  _  _  _  _ _ _ $_ $_ $_ $_ $_ $_ $_ $_ $_ $ _ $ _ $ _ $ _ $ _ $_ $%%PA611 MULTI-READER PUNCH EXERCISER%SET SR TO VECTOR OF READER 0%SET SR TO READERS TO TEST%SET SR TO CODE LEVEL-UP=8 DOWN=6%SET SR TO PUNCHES TO TEST%%MORE THAN 16 READERS ON SYSTEM%%MORE THAN 16 PUNCHES ON SYSTEM%%NON-EXISTENT READER SELECTED^PlpE*<  pE<p**<<Bo`*@8 pE 6p`.`*6`2[(ݩA@8E X ݩA.]X N_"+}sL9(dΫ@QNO.z7 xp7 (F(w(@QKhxpx(@ @.F@@yΫ@(dΫ@P@p@_.@_@}@NO@A@0z1.|/' PSEGX NSEGX NSEGP POLY'' NSEGA 3. YENDL XL DXL'' ZL0" DZL')Y,Oi; vݩ`Z,@8E@8  ZS2^,S2^ -}; vb.S4; vb S4;*, vS4;  v*S4vQ*; 3N@D< 84*4 27 27 , e p ,5M*4w  wd w   7!  *44 e---*5 4 54M*$5wXhfdbb`l*H5^\PTRPL0*l5FD:<:84 |*5., o@@*5F5 5% DROPPED OFFENDING ROM,.@@8*@@8@@@Q@.@@@(ݩ@ݩ@.T@pE@@8E@P;@L9@@8.@p@+}s@S3gxp.&\&&$ v}~@\\2\ .qDw J F v C@w *SDF @PJ| v PC<w PJ(r| <u v PC 8w PJ v *U 8 dPC4w5v S4 S27@8*(;P v S4 ;P6, vS4;P  vS4BH(;P vH S4 ;PN}, vS4S2 7p7%$\j(5I6,5F10.4) h.j v S2.x(//' INTL DIN&S2-}7%.TL NSEL YENDR XR'' 8 %|*5KWAD0f@f6f6*6f6*:6e*^65w8w|6=*6НvU@? b65X 6*657 vFBp>68(\*650eNJLED? > <.*6E265 "-< w *7,J7 755.7% RUN TI*67ME IS APPROXIMATELY . MUNITES %Z7g PJ $ v PC(4$ 0w PJ \ v PC,w *0\ ,PJv PC(w PJ((zbv PC &w Jjv * &jnNC"w PJ v PC("`yw PJ v PCw *yTPJv PCw PJ(oHHv PC w PJv *H<9 D.XR ZR DZR'),Oi ";$ &v(ݩ X,@8E@8  XS2\,S2\ -};P v N*S4;P v S4S2jv*7p; vj S4S2Y&#.7@8;P v S4;P4\ , vS4;P  v\ PCw PJ v PC(. w PJ v PCw * "cJv Cw J(7'*v C w Jv ** lCw J bv C(bw Jv C,[ @8E  ݩA,B@`̫')D.TEORAB=S4@$ (;P v$  S4 ;PL , v S4S2 7p7% *Zn(2F10.4,I6,5F10.4) #.n v  "S2$.|(//' INTR DIN&S2-}7%&TR NSER I')<,Oi; v ݩD /,:p Ep   m9 KB JO, KSOCBLT ENGMSEE RE FREMOO N('.%7}-  2S2S,x v   } ,x @8E @8 ݩv *|FCfO  }. v (. l芊 jv ;,lj\芊F v  ;Pʫv ,F NP; p Pʫ*S2S2  -};P" | , v S4;P  v| S4F *S27p ;  vF S4m.S27@8 S2 S27@87%" (2F10.4,2I6)  * v  &?.}Oi  @8;56( vʫ p ;PDB( v