|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T p
Length: 14955 (0x3a6b) Types: TextFile Names: »ped.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec1/ped/ped.c«
/* * ped - the picture editor for GIGIs. * Col. G. L. Sicherman (decvax!sunybcs!colonel). Circa 1984. * Version 1. (This does not imply that any newer versions will * be developed!) * * Copyright 1987 by G. L. Sicherman. You may use and alter * this program however you like, so long as you do not claim * it as your own, try to get money for it, or alter this * message. * * This is meant for UNIX BSD4. It has not been extensively * tested. It comes with no guarantees. */ #include <sgtty.h> #include <signal.h> #include <ctype.h> #include <stdio.h> #include "gigi.h" /* * Shell escape. */ #define SHELL "/bin/csh" /* * Storage parameters. */ #define MAXPOINTS 300 #define MAXLINES 384 #define MAXCIRC 50 #define MAXOPECURV 100 #define MAXLOOPS 100 char *version = "1"; int x=300, y=200; /* STARTING POINT */ int xfac=1, yfac=1; int vx, vy, vp; int cx, cy, cp; struct spl_ *cs; int npoints=0, nlines=0, nsplines=0, ncirc=0, nloops=0; int grid=0; /* DRAW A GRID? */ int labelpts=1; /* LABEL THE POINTS? */ char splinetype; /* S FOR OPEN, B FOR CLOSED */ int vector=0; /* DRAWING VECTORS? */ int curve=0; /* DRAWING SPLINE? */ int circle=0; /* DRAWING CIRCLE? */ int moving=0; /* RELOCATING A POINT? */ int param=0; int nchanges = 0; char fname[72]; FILE *fstr; int atpoint=0; struct sgttyb oldt, newt; struct ct { int cce, cci; } circ[MAXCIRC]; struct pt { int px, py; } point[MAXPOINTS]; struct ln { int l0, l1; } line[MAXLINES]; struct spl_ { int s0; struct spl_ *s1; } *spline[MAXOPECURV], *loop[MAXLOOPS]; main(argc,argv) int argc; char **argv; { int i, quit(); int nquits = 0, nexpunges = 0; char cmd, oldcmd='q'; if (argc>2) { fprintf(stderr,"usage: ped [file]\n"); exit(1); } gtty(0,&oldt); signal(SIGINT,quit); newt=oldt; newt.sg_flags |= CBREAK; newt.sg_flags &= ~ECHO; stty(0,&newt); puts(GR_ON,stdout); puts(RESET,stdout); printf("S(E)(I(D))\n"); if (argc==2) { loadfrom(argv[1]); redraw(stdout); } mvcur(); /* * The command loop. */ for (;;) { if (1>read(0,&cmd,1)) quit(); if (cmd!='q') nquits=0; if (cmd!='x') nexpunges=0; if (cmd!='h' && cmd!='l' && !isdiag(cmd)) xfac=1; if (cmd!='j' && cmd!='k' && !isdiag(cmd)) yfac=1; if (isorth(cmd) || isdiag(cmd)) atpoint=0; if (cmd!=oldcmd) xfac=yfac=1; if (isdigit(cmd)) { param=param*10+cmd-'0'; continue; } switch (cmd) { case '?': help(); break; case '!': escape(); break; case 'q': if (nchanges && !nquits++) beep(); else quit(); break; case 'r': redraw(stdout); break; case 's': scaleup(); break; case 'g': grid = !grid; redraw(stdout); break; case 'f': for (i=0; i<npoints; i++) point[i].py=479-point[i].py; redraw(stdout); nchanges++; break; case 'J': if (!param) param=1; for (i=0; i<npoints; i++) point[i].py+=param; redraw(stdout); nchanges++; break; case 'K': if (!param) param=1; for (i=0; i<npoints; i++) point[i].py-=param; redraw(stdout); nchanges++; break; case 'L': dsplines(); break; case 'm': if (param) { if (param>npoints) { beep(); break; } gopoint(param); } else if (!atpoint) mkpoint(); moving=atpoint; vector=0; printf("W(I%d)V[]W(I%d)\n",GR_RED,GR_WHITE); nchanges++; break; case 'k': hjkl(0,-1); break; case 'j': hjkl(0,1); break; case 'h': hjkl(-1,0); break; case 'l': hjkl(1,0); break; case 'y': hjkl(-1,-1); break; case 'u': hjkl(1,-1); break; case 'b': hjkl(-1,1); break; case 'n': hjkl(1,1); break; case 'e': printf("%s\n",GR_OFF); stty(0,&oldt); printf("File name: "); if (1==scanf(" %s",fname)) loadfrom(fname); stty(0,&newt); printf("%s\n",GR_ON); redraw(stdout); break; case 'w': printf("%s\n",GR_OFF); stty(0,&oldt); printf("File name: "); if (1==scanf(" %s",fname)) { fstr=fopen(fname,"w"); if (fstr==NULL) printf("cannot open %s\n",fname); else { labelpts=0; fprintf(fstr,"%s\n",GR_ON); fprintf(fstr,"%s\n",RESET); strucdump(fstr); redraw(fstr); fprintf(fstr,"%s\n",GR_OFF); labelpts=1; fclose(fstr); printf("Dumped.\n"); } } while ('\n'!=getchar()); /* FLUSH INPUT LINE */ nchanges=0; stty(0,&newt); printf("%s\n",GR_ON); break; case 'x': if (!atpoint) beep(); else if (!nexpunges++ && pointused(atpoint)) beep(); else { delpoint(atpoint); redraw(stdout); } break; case 'V': for (i=1; i<=npoints; i++) if (!pointused(i)) delpoint(i); redraw(stdout); break; case 'o': case 'z': if (vector || curve || circle) beep(); else { curve=1; splinetype = 'o'==cmd? 'S': 'B'; cx=x; cy=y; if (!atpoint) mkpoint(); cs = (struct spl_ *)malloc(sizeof(struct spl_)); if (cmd=='o') spline[nsplines]=cs; else loop[nloops]=cs; cs->s0 = cp = atpoint; cs->s1 = NULL; } break; case 'c': if (vector || curve || circle) beep(); else { circle=1; cx=x; cy=y; } if (!atpoint) mkpoint(); cp=atpoint; break; case 'v': if (vector || curve || circle) beep(); else { vector=1; vx=x; vy=y; } if (!atpoint) mkpoint(); vp=atpoint; break; case 'p': if (param) { if (param>npoints || moving) { beep(); break; } else gopoint(param); } else if (moving) { point[moving-1].px=x; point[moving-1].py=y; printf("V[]T'%d'P[%d,%d]\n",moving,x,y); moving=0; } else mkpoint(); if (curve) xtndspline(); else if (circle) { printf("P[%d,%d]C[%d,%d]\n",cx,cy,x,y); circ[ncirc].cce=cp; circ[ncirc].cci=param; ncirc++; nchanges++; circle=0; } else if (vector) { printf("P[%d,%d]V[%d,%d]\n",vx,vy,x,y); vx=x; vy=y; line[nlines].l0=vp; line[nlines].l1=param; nlines++; nchanges++; vp=param; } break; case 'i': if (vector) vector=0; else if (curve) { curve=0; if (!atpoint) { mkpoint(); xtndspline(); } if (splinetype=='S') nsplines++; else nloops++; } else beep(); break; default: beep(); } oldcmd=cmd; param=0; } } escape() { printf("%s\n",GR_OFF); system(SHELL); cntinu(); } help() { printf("%s\n",GR_OFF); printf("?\tmenu\t\t\tn\tdown right\n"); printf("J\tpicture down\n"); printf("K\tpicture up\n"); printf("L\tshow lines\t\to\topen curve\n"); printf("V\tdelete unused points\tp\tpoint\n"); printf("b\tdown left\t\tq\tquit\n"); printf("c\tcircle\t\t\tr\tredraw screen\n"); printf("e\tedit a ped file\t\ts\tscale up or down\n"); printf("f\tflip picture\n"); printf("g\tdraw/erase grid\t\tu\tup right\n"); printf("h\tleft\t\t\tv\tbegin vectors\n"); printf("i\tend vector/curve\tw\twrite to file\n"); printf("j\tdown\t\t\tx\tremove point\n"); printf("k\tup\t\t\ty\tup left\n"); printf("l\tright\t\t\tz\tloop (closed curve)\n"); printf("m\tmove point\n"); cntinu(); } mvcur() { printf("P[%d,%d]\n",x,y); } quit() { puts(GR_OFF,stdout); stty(0,&oldt); exit(0); } beep() { printf("\007"); fflush(stdout); } redraw(stm) FILE *stm; { int i; fprintf(stm,";S(E)\n"); if (labelpts && grid) { fprintf(stm,"W(I(G))\n"); for (i=1; i<8; i++) fprintf(stm,"P[%d,1]V[,+470]\n",i*100); for (i=1; i<5; i++) fprintf(stm,"P[1,%d]V[+760]\n",i*100); fprintf(stm,"W(I(W))\n"); } for (i=0; i<npoints; i++) { if (labelpts) fprintf(stm,"P[%d,%d]V[]T'%d'\n",point[i].px,point[i].py, i+1); fprintf(stm,"P[%d,%d]\n",point[i].px,point[i].py); x=point[i].px; y=point[i].py; atpoint=i; } for (i=0; i<nlines; i++) { fprintf(stm,"P[%d,%d]V[%d,%d]\n", point[line[i].l0-1].px,point[line[i].l0-1].py, point[line[i].l1-1].px,point[line[i].l1-1].py); x=point[line[i].l1-1].px; y=point[line[i].l1-1].py; atpoint=line[i].l1; } if (labelpts) fprintf(stm,"W(I%d)\n",GR_YELLOW); for (i=0; i<ncirc; i++) fprintf(stm,"P[%d,%d]C[%d,%d]\n", point[circ[i].cce-1].px, point[circ[i].cce-1].py, point[circ[i].cci-1].px, point[circ[i].cci-1].py); if (labelpts) fprintf(stm,"W(I%d)\n",GR_WHITE); for (i=0; i<nsplines; i++) drawspl(stm,'S',i+1); for (i=0; i<nloops; i++) drawspl(stm,'B',i+1); } mkpoint() { point[npoints].px=x; point[npoints].py=y; printf("V[]T'%d'P[%d,%d]\n",++npoints,x,y); atpoint=param=npoints; nchanges++; } dsplines() { int i; puts(GR_OFF,stdout); printf("LineNo\tStart\tX\tY\tEnd\tX\tY\n"); for (i=0; i<nlines; i++) printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\n", i+1,line[i].l0,point[line[i].l0-1].px,point[line[i].l0-1].py, line[i].l1,point[line[i].l1-1].px,point[line[i].l1-1].py); cntinu(); } gopoint(param) int param; { x=point[param-1].px; y=point[param-1].py; mvcur(); atpoint=param; } xtndspline() { cs->s1 = (struct spl_ *)malloc(sizeof (struct spl_)); cs=cs->s1; cs->s0 = atpoint; cs->s1 = NULL; drawspl(stdout,splinetype,(splinetype=='S'? nsplines: nloops)+1); nchanges++; } drawspl(stm,t,i) char t; int i; FILE *stm; { struct spl_ *s; if (t=='S') s = spline[i-1]; else s = loop[i-1]; fprintf(stm,"P[%d,%d]C(%c)\n", point[s->s0-1].px,point[s->s0-1].py,t); while (s = s->s1) fprintf(stm,"[%d,%d]\n", x=point[(atpoint=s->s0)-1].px,y=point[s->s0-1].py); fprintf(stm,"C(E)\n"); } hjkl(dx,dy) int dx, dy; { if (param) { x+=param*dx; xfac=1; y+=param*dy; yfac=1; } else { x+=xfac*dx; xfac*=2; if (xfac>100) xfac=100; y+=yfac*dy; yfac*=2; if (yfac>100) yfac=100; } if (x<0) x=0; if (x>767) x=767; if (y<0) y=0; mvcur(); } int isorth(c) char c; { return c=='h' || c=='j' || c=='k' || c=='l'; } int isdiag(c) char c; { return c=='y' || c=='u' || c=='b' || c=='n'; } cntinu() { char c; printf("\nType space to continue"); fflush(stdout); while (1==read(0,&c,1)) if (c==' ') break; puts(GR_ON,stdout); redraw(stdout); } strucdump(str) FILE *str; { int i; struct spl_ *s; fprintf(str,";\"\n"); fprintf(str,"%d\n",npoints); for (i=0; i<npoints; i++) fprintf(str,"%d %d\n",point[i].px,point[i].py); fprintf(str,"%d\n",nlines); for (i=0; i<nlines; i++) fprintf(str,"%d %d\n",line[i].l0,line[i].l1); fprintf(str,"%d\n",ncirc); for (i=0; i<ncirc; i++) fprintf(str,"%d %d\n",circ[i].cce,circ[i].cci); fprintf(str,"%d\n",nsplines); for (i=0; i<nsplines; i++) { for (s=spline[i]; s; s=s->s1) fprintf(str,"%d ",s->s0); fprintf(str,"-1 \n"); } fprintf(str,"%d\n",nloops); for (i=0; i<nloops; i++) { for (s=loop[i]; s; s=s->s1) fprintf(str,"%d ",s->s0); fprintf(str,"-1 \n"); } fprintf(str,"\"\n"); } loadfrom(fname) char *fname; { FILE *str; char k; int i, j; struct spl_ *s; str=fopen(fname,"r"); if (str==NULL) { printf("cannot read %s\n",fname); return; } for (i=0; i<2; i++) while (';'!=(k=getc(str))) if (EOF==k) { printf("Error in file; load aborted.\n"); return; } if ('"'!=getc(str)) { printf("Error in file; load aborted.\n"); return; } fscanf(str," %d",&npoints); for (i=0; i<npoints; i++) fscanf(str," %d %d",&point[i].px,&point[i].py); fscanf(str," %d",&nlines); for (i=0; i<nlines; i++) fscanf(str," %d %d",&line[i].l0,&line[i].l1); fscanf(str," %d",&ncirc); for (i=0; i<ncirc; i++) fscanf(str," %d %d",&circ[i].cce,&circ[i].cci); fscanf(str," %d",&nsplines); for (i=0; i<nsplines; i++) { s=spline[i]=(struct spl_ *)malloc(sizeof (struct spl_)); fscanf(str," %d",&(s->s0)); for (;;) { fscanf(str," %d",&j); if (j<0) break; s=s->s1=(struct spl_ *)malloc(sizeof (struct spl_)); s->s0=j; } s->s1=0; } fscanf(str," %d",&nloops); for (i=0; i<nloops; i++) { s=loop[i]=(struct spl_ *)malloc(sizeof (struct spl_)); fscanf(str," %d",&(s->s0)); for (;;) { fscanf(str," %d",&j); if (j<0) break; s=s->s1=(struct spl_ *)malloc(sizeof (struct spl_)); s->s0=j; } s->s1=0; } fclose(str); } scaleup() /* SCALE THE WHOLE PICTURE UP OR DOWN */ { int i; double fac; printf("%s\n",GR_OFF); stty(0,&oldt); printf("Scale factor: "); if (1==scanf(" %lf",&fac)) { if (0.0==fac) printf("That's too small\n"); else for (i=0; i<npoints; i++) scalpoint(&point[i],fac); } else printf("* Ignored *\n"); while ('\n'!=getchar()); /* FLUSH INPUT LINE */ stty(0,&newt); printf("%s\n",GR_ON); redraw(stdout); } scalpoint(p,f) struct pt *p; double f; { int newx, newy; newx=384+f*(p->px-384); newy=240+f*(p->py-240); if (newx<0) { newy=((p->py-240)*(p->px-384))/384 + 240; newx=0; } else if (newx>767) { newy=((p->py-240)*(p->px-384))/384 + 240; newx=767; } if (newy<0) { newx=((p->px-384)*(p->py-240))/240 + 384; newy=0; } else if (newy>479) { newx=((p->py-384)*(p->px-240))/240 + 384; newy=479; } p->px=newx; p->py=newy; } delpoint(n) int n; /* DELETE POINT N AND RENUMBER REMAINING POINTS */ { int i; struct spl_ *s; if (n>npoints) { beep(); return; } if (pointused(n)) delrefs(n); for (i=n-1; i<npoints-1; i++) point[i]=point[i+1]; for (i=0; i<nlines; i++) { if (line[i].l0>n) line[i].l0--; if (line[i].l1>n) line[i].l1--; } for (i=0; i<ncirc; i++) { if (circ[i].cce>n) circ[i].cce--; if (circ[i].cci>n) circ[i].cci--; } for (i=0; i<nsplines; i++) { s=spline[i]; while (s) { if (s->s0>n) s->s0--; s=s->s1; } } for (i=0; i<nloops; i++) { s=loop[i]; while (s) { if (s->s0>n) s->s0--; s=s->s1; } } npoints--; } delrefs(n) /* DELETE LINES & CURVES CONTAINING POINT n */ { int i, j; struct spl_ **s; for (i=0; i<nlines; i++) if (line[i].l0==n || line[i].l1==n) { for (j=i; j<nlines-1; j++) line[j]=line[j+1]; nlines--; i--; } for (i=0; i<ncirc; i++) if (circ[i].cce==n || circ[i].cci==n) { for (j=i; j<ncirc-1; j++) circ[j]=circ[j+1]; ncirc--; i--; } for (i=0; i<nsplines; i++) { s = &spline[i]; while (*s) { if ((*s)->s0==n) *s = (*s)->s1; else s = &((*s)->s1); } } for (i=0; i<nloops; i++) { s = &loop[i]; while (*s) { if ((*s)->s0==n) *s = (*s)->s1; else s = &((*s)->s1); } } } int pointused(n) int n; /* IS POINT PART OF A LINE OR CURVE? */ { int i; struct spl_ *s; for (i=0; i<nlines; i++) if (line[i].l0==n || line[i].l1==n) return 1; for (i=0; i<ncirc; i++) if (circ[i].cce==n || circ[i].cci==n) return 1; for (i=0; i<nsplines; i++) { s=spline[i]; while (s) { if (s->s0==n) return 1; s=s->s1; } } for (i=0; i<nloops; i++) { s=loop[i]; while (s) { if (s->s0==n) return 1; s=s->s1; } } return 0; } mrgpts(i,j) /* MERGE TWO POINTS INTO ONE */ int i, j; { int k; struct spl_ *s; if (i>j) { k=i; i=j; j=k; } for (k=0; k<nlines; k++) { if (line[k].l0==j) line[k].l0=i; if (line[k].l1==j) line[k].l1=i; } for (k=0; k<ncirc; k++) { if (circ[k].cce==j) circ[k].cce=i; if (circ[k].cci==j) circ[k].cci=i; } for (k=0; k<nsplines; k++) { s=spline[k]; while (s) { if (s->s0==j) s->s0=i; s=s->s1; } } for (k=0; k<nloops; k++) { s=loop[k]; while (s) { if (s->s0==j) s->s0=i; s=s->s1; } } delpoint(j); }