# GPACK(2) # # Graphics Package # # Stephen B. Wampler # # Last modified 7/10/83 # ### note - currently no clipping is performed. needs work. global _wno # current window runner global Window global Wscale # list of window attributes global MODE, ESC # chromatic commands global OFF, ON global DOT, VECTOR, RECTANGLE, CIRCLE, ARC, CONCVECT, INCDOT global XMAX, YMAX global BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, YELLOW, WHITE, BLINK # set the mode # procedure clip(mode) suspend Window[_wno].cmode <- mode # mode is ON/OFF end # clip the object # procedure clipped(object) case type(object) of { default: return object } end # set the color # procedure color(colr) if colr % 8 ~= Window[_wno].fc then { writes(MODE,"C",colr % 8) Window[_wno].fc := colr % 8 } return end # set the background color # procedure bckgrnd(colr) if colr % 8 ~= Window[_wno].bc then { writes(MODE,"M") writes(MODE,"C",colr % 8) Window[_wno].bc := colr % 8 writes(MODE,"N") } return end # set the cursor color # procedure curcol(colr) writes(MODE,"Q",colr % 8) return end # enable particular color guns # procedure enable(colr) writes(MODE,":","0123456789ABCDEF"[colr+1]) return end # draw an object # procedure draw(object) local pts, p0 if /object then fail object := clipped(object) | fail every _plot() do { # switch to plot mode case type(object) of { "co-expression": while draw(@object) "motion": { _xydel(object.xdel,object.ydel) } "point": { _point(object.x,object.y) } "dot": { mode(DOT) _point(object.x,object.y) } "line": { mode(VECTOR) _point(object.a.x,object.a.y) _point(object.b.x,object.b.y) } "box": { mode(RECTANGLE) _point(object.a.x,object.a.y) _point(object.b.x,object.b.y) } "circle": { mode(CIRCLE) _point(object.center.x,object.center.y) _number(object.radius) } "arc": { mode(ARC) _point(object.center.x,object.center.y) _number(object.radius) _number(object.start) _number(object.stop) } "points": { mode(DOT) every draw(!(object.pts)) } "lines": { pts := create !object.pts p0 := @pts mode(VECTOR) while draw(line(.p0,p0 := @pts)) } "polygon": { mode(VECTOR) draw(lines(object.pts)) draw(line(object.pts[0],object.pts[1])) } "incdots": { mode(INCDOT) draw(object.start) every draw(!object.motions) } default : write(&errout,"don't know how to draw ",type(object)) } } return end # clear the screen procedure erase() writes("\014") return end # switch to fill mode # procedure _fill() if Window[_wno].fmode == OFF then { writes(MODE,"F") suspend Window[_wno].fmode <- ON writes(MODE,"L") fail } return end # leave fill mode # procedure _nofill() if Window[_wno].fmode == ON then { writes(MODE,"L") suspend Window[_wno].fmode <- OFF writes(MODE,"F") fail } return end # initialize # procedure ginit() MODE := "\01" ESC := "\033" ON := "on" OFF := "off" XMAX := 511 YMAX := 511 Window := list(4) every Window[1 to 4] := wind(OFF,OFF,OFF,OFF,ON,"",-1,-1,point(0,0),point(511,511)) every window(1 to 4) do { writes(MODE,"\25") # plot off writes(MODE,"L") # fill off writes(MODE,"R") # roll on } Wscale := list(4) every Wscale[1 to 4] := scaling(1,0,1,0) _wno := 1 DOT := "%" VECTOR := "'" RECTANGLE := "+" CIRCLE := "*" ARC := ")" CONCVECT := ")" INCDOT := "&" BLACK := 0 BLUE := 1 GREEN := 2 CYAN := 3 RED := 4 MAGENTA := 5 YELLOW := 6 WHITE := 7 BLINK := 8 end # set plot submode (internal routine) # procedure mode(newmode) if newmode ~== Window[_wno].psubmode then { writes(newmode) suspend Window[_wno].psubmode <- newmode writes(Window[_wno].psubmode) fail } return end # move cursor to (x,y) (internal routine) # procedure movcur(x,y) writes(MODE,"U") _point(x,y) return end # switch to plot mode # procedure _plot() if Window[_wno].pmode == OFF then { Window[_wno].psubmode := " " writes(MODE,"G") suspend Window[_wno].pmode <- ON writes("\25") fail } return end # switch to character mode # procedure _char() if Window[_wno].pmode == ON then { writes("\25") suspend Window[_wno].pmode <- OFF writes(MODE,"G") fail } return end # put out a point (x,y) (internal routines) # write a point # procedure _point(x,y) _number(xfit(x)) _number(yfit(y)) return end # write a number # procedure _number(n) if n <= 99 then writes(n,",") else writes(n) return end # graphic record types record point(x,y) record dot(x,y) record line(a,b) record box(a,b) record circle(center,radius) record arc(center,radius,start,stop) record points(pts) record lines(pts) record polygon(pts) record incdots(start,motions) record motion(xdel,ydel) # window records record wind(pmode,smode,cmode,fmode,rmode,psubmode,fc,bc,lowerleft,upperright) record scaling(xslope,xinter,yslope,yinter) # reset windows # procedure restore() every window(3 to 0 by -1) do { setscale(0,0,511,511,0,0,511,511) wsize(0,0,511,511) _char() _roll() enable(WHITE+BLINK) } end # turn on roll # procedure _roll() if Window[_wno].rmode ~== ON then { writes(MODE,"R") suspend Window[_wno].rmode <- ON writes(MODE,"P") fail } return end # turn off roll # procedure _noroll() if Window[_wno].rmode ~== OFF then { writes(MODE,"P") suspend Window[_wno].rmode <- OFF writes(MODE,"R") fail } return end procedure setscale(xmin,ymin,xmax,ymax,colmin,rowmin,colmax,rowmax) Wscale[_wno].xslope := real(colmax-colmin) / (xmax-xmin) Wscale[_wno].xinter := colmin - xmin * Wscale[_wno].xslope Wscale[_wno].yslope := real(rowmax-rowmin) / (ymax-ymin) Wscale[_wno].yinter := rowmin - (ymin * Wscale[_wno].yslope) return end procedure xfit(x) if Window[_wno].smode === ON then return integer(Wscale[_wno].xslope * x + Wscale[_wno].xinter + 0.5) else return integer(x + 0.5) end procedure yfit(y) if Window[_wno].smode === ON then return integer(Wscale[_wno].yslope * y + Wscale[_wno].yinter + 0.5) else return integer(y + 0.5) end procedure scale(pt) if Window[_wno].smode === ON then return point( integer(Wscale[_wno].xslope * pt.x + Wscale[_wno].xinter + 0.5), integer(Wscale[_wno].yslope * pt.y + Wscale[_wno].yinter + 0.5) ) else return pt end procedure _scale(mode) suspend Window[_wno].smode <- mode end # place text on screen at (x,y) # procedure text(x,y,s) every _char() do { movcur(x,y) writes(s) } return end # switch to window w (0-3) # procedure window(w) writes(ESC,"OA",w % 4) _wno := w % 4 + 1 return end # set new window size # procedure wsize(x0,y0,x1,y1) writes(MODE,"W") _point(x0,y0) _point(x1,y1) Window[_wno].lowerleft := point(x0,y0) Window[_wno].upperright := point(x1,y1) return end # output deltax, deltay to terminal # procedure _xydel(xdel,ydel) local signx, signy, byte static chars initial chars := string(&cset) signx := signy := 0 if xdel < 0 then { signx := 32 xdel := -xdel } if ydel < 0 then { signy := 4 ydel := -ydel } byte := 64 + signx + xdel*8 + signy + ydel writes(chars[65 + signx + (xdel % 4)*8 + signy + (ydel % 4)]) return end