C ============================================================================ C C PLOT - NOEL CARBONI - 5/13/81 C C THIS IS A SUBROUTINE WHICH ENABLES PLOTTING ON THE DIABLO 1750 LETTER C QUALITY PRINTER. C C OUTPUT TO THE PRINTER WILL BE THROUGH LUN 2 C C C TO USE: COMPILE, THEN WHEN NEEDED LINK THIS SUBROUTINE TO THE CALLING C PROGRAM. LUN 2 WILL NEED TO BE RE-ASSIGNED. C C EX: >FOR PLOT=PLOT ; (ONLY NEED BE DONE INITIALLY) C C >TKB PROG=PROG,PLOT ; TASK BUILD C >INS PROG ; INSTALL TASK C >REA PROG 2 TTn: ; REASSIGN LUN 2 TO APPROPRIATE C ; TT NUMBER. C C C PLOT WILL ALLOW THE PLOTTING OF A LINE OR A DOT, DEPENDING ON THE VALUE C OF THE THIRD ARGUMENT IN THE CALL STATEMENT: C C CALL PLOT (X,Y,0) WILL CAUSE THE CURSOR TO MOVE TO POSITION X,Y. C C CALL PLOT (X,Y,1) WILL CAUSE THE CURSOR TO MOVE TO POSITION X,Y AND PLOT C A DOT THERE. C C CALL PLOT (X,Y,2) WILL CAUSE A LINE TO BE PLOTTED FROM THE LAST CURSOR C POSITION TO X,Y C C CALL PLOT (X,Y,C) WHERE C IS ANY CHARACTER STRING WILL CAUSE THE CHARACTERS C TO BE PRINTED AT POSITION X,Y. THE CURSOR WILL BE LEFT C AT THE NEXT AVAILABLE CHARACTER POSITION. C C C *NOTE*: X IS ZERO AT THE LEFT EDGE OF THE PAPER, AND INCREASES TO THE RIGHT C AND Y IS ZERO AT THE TOP EDGE OF THE PAPER, AND INCREASES DOWNWARD. C C C CALL PLOT (-1) EJECTS A PAGE AND INITIALIZES THE PRINTER TO PLOT MODE C THIS SHOULD BE THE FIRST CALL TO PLOT. C C CALL PLOT (-2) EJECTS A PAGE AND RETURNS THE PRINTER TO CHARACTER MODE C THIS SHOULD BE THE LAST CALL TO PLOT. C C CALL PLOT (-3) IS THE SAME AS CALL PLOT(-1) EXCEPT THAT HIDDEN LINE C HORIZONS ARE TO BE MAINTAINED. I.E. IF A SOLID OBJECT C IS TO BE PLOTTED, AND HIDDEN LINES ARE NOT TO BE SHOWN, C THE PROCEDURE IS AS FOLLOWS: C 1) PLOT THE CLOSEST (TO THE VIEWER) POINTS OF THE C OBJECT FIRST. C 2) POINTS FARTHER BACK THAT ARE NOT VISIBLE WILL NOT C BE PLOTTED. C C C ============================================================================ SUBROUTINE PLOT(X,Y,CHARS) IMPLICIT INTEGER (A-Z) BYTE CHARS(132),DOWN,LEFT,RIGHT,DOT DIMENSION MY(500,2),P(1000,2) DOUBLE PRECISION INCREM,TX,TY DATA UP,STPLOT/2587,13083/ ! & '3' DATA DOWN,LEFT,RIGHT,DOT/10,8,32,'.'/ DATA FONT/5/ ! 5 IS ELITE, 6 IS PICA DATA MY/500*10000,500*-10000/ 1 FORMAT('+',A1,$) ! FORMAT TO PRINT SINGLE CHAR 2 FORMAT('+',A2,$) ! DOUBLE CHARACTER FORMAT C ============================================================================ C C BEGIN EXECUTABLE CODE C C ============================================================================ MODE = CHARS(1) IF (X.EQ.-1) GOTO 1000 ! INITIALIZE IF (X.EQ.-3) GOTO 1000 ! INITIALIZE TO HORIZON MODE IF (X.EQ.-2) GOTO 2000 ! FINISH IF (X.LT.0) X=0 ! LET ONLY POSITIVE VALUES THRU IF (Y.LT.0) Y=0 PCTR=0 ! CTR OF NO. OF POINTS PLOTTED IF (MODE.EQ.2) GOTO 5000 ! DRAW LINE GOTO 4000 ! ALL OTHERS INTERPRETED AS C ! MOVE TO X,Y C ============================================================================ C C INITIALIZATION SECTION C C INITIALIZE PRINTER TO PLOT MODE, AND HOME CURSOR TO 0,0 C C ============================================================================ 1000 WRITE(2,1010) ! EJECT PAGE 1010 FORMAT('1'$) WRITE(2,2) STPLOT ! SET PRINTER TO PLOT MODE HIDDEN=0 ! DEFAULT TO NON - HIDDEN MODE IF (X.EQ.-3) HIDDEN=1 ! WANTS HIDDEN LINES HIDDEN LASTPL=0 ! LAST POSITION NOT PLOTTED OLDX=0 ! CURRENT CURSOR POSITION OLDY=0 RETURN ! RETURN TO CALLER C ============================================================================ C C FINISH SECTION C C PAGE EJECT, SET PRINTER BACK INTO CHARACTER MODE C C ============================================================================ 2000 WRITE(2,2010) ! IT'S THE WE NEED TO PUT 2010 FORMAT(' ') ! THE PRINTER OUT OF PLOT MODE WRITE(2,2020) ! EJECT PAGE 2020 FORMAT('1'$) RETURN ! GO BACK TO CALLER C ============================================================================ C C MOVE CURSOR SECTION C C MOVE FIRST IN THE X DIRECTION, AND THEN IN THE Y DIRECTION C C ============================================================================ 4000 LASTPL = 0 ! DEFAULT X,Y NOT PLOTTED IF (X.LT.OLDX) GOTO 4100 ! RIGHT TO LEFT MOVEMENT IF (X.EQ.OLDX) GOTO 4500 ! NO HORIZONTAL MOVEMENT AT ALL IX=X-1 ! MOVE LEFT TO RIGHT HERE DO 4010 I=OLDX,IX ! MAKE X-OLDX-1 MOVES WRITE(2,1) RIGHT ! TO THE RIGHT 4010 CONTINUE ! LOOP TILL DONE GOTO 4500 ! GO DO VERTICAL MOVEMENT NOW 4100 IX=X+1 ! MOVE RIGHT TO LEFT HERE DO 4110 I=IX,OLDX ! MAKE OLDX-X-1 MOVES WRITE(2,1) LEFT ! TO THE LEFT 4110 CONTINUE ! LOOP TILL DONE 4500 IF (Y.LT.OLDY) GOTO 4600 ! UPWARD MOVEMENT NEEDED IF (Y.EQ.OLDY) GOTO 4700 ! NO VERTICAL MOVEMENT NEEDED IY=Y-1 ! MOVE DOWNWARD HERE DO 4510 I=OLDY,IY ! MAKE Y-OLDY-1 MOVES WRITE(2,1) DOWN ! DOWNWARD 4510 CONTINUE ! LOOP TILL DONE GOTO 4700 ! DONE WITH MOVEMENT 4600 IY=Y+1 ! MOVE UP HERE DO 4610 I=IY,OLDY ! MAKE OLDY-Y-1 MOVES WRITE(2,2) UP ! UPWARD 4610 CONTINUE ! LOOP TILL DONE 4700 IF (MODE.EQ.0) GOTO 9999 ! JUST MOVE - GO RETURN IF (MODE.GE.32) GOTO 4800 ! PRINT CHARACTERS - BRANCH IF (Y.GE.MY(X,1).AND.Y.LE.MY(X,2)) GOTO 9999 WRITE(2,1) DOT ! MOVE THEN PLOT DOT SECTION PCTR=PCTR+1 P(PCTR,1)=X P(PCTR,2)=Y LASTPL=1 ! LAST POSITION PLOTTED GOTO 9999 ! GO RETURN 4800 I=1 ! PRINT CHARACTERS IX=X ! COUNTER OF POSITION 4810 IF (CHARS(I).LT.32.OR.CHARS(I).GT.126) GOTO 4999 ! FINISHED? IF (CHARS(I).EQ.32) GOTO 4815 ! JUST MOVE RIGHT IF BLANK WRITE(2,1) CHARS(I) ! PRINT THE CHARACTER 4815 DO 4820 J=1,FONT ! MOVE FONT DOT POSITIONS WRITE(2,1) RIGHT ! TO THE RIGHT 4820 CONTINUE ! LOOP TILL DONE IX=IX+FONT ! REMEMBER WHERE WE ARE I=I+1 ! INCREMENT TO NEXT CHARACTER GOTO 4810 ! GO TEST THIS ONE 4999 OLDX=IX ! REMEMBER WHERE THE CURSOR IS OLDY=Y RETURN ! BACK TO CALLER C ============================================================================ C C LINE DRAW SECTION C C DRAWS A LINE FROM LAST CURSOR POSITION (OLDX,OLDY) TO (X,Y) C C ============================================================================ 5000 DX = X - OLDX ! CHANGE IN THE X DIRECTION DY = Y - OLDY ! CHANGE IN THE Y DIRECTION IF (IABS(DX).LT.IABS(DY)) GOTO 5500 ! HOW SLANTED IS THE LINE? C C LINE IS MORE HORIZONTAL THAN VERTICAL HERE C KX=IABS(DX) ! NUMBER OF X MOVES TO MAKE IF (KX.EQ.0) GOTO 9999 ! DON'T NEED TO MOVE AT ALL INCREM = FLOAT(DY)/IABS(DX) ! FIND Y MOVE FOR EVERY 1 X TY = OLDY + 0.5 ! INITIAL Y POSITION IF (LASTPL.EQ.1.OR.(OLDY.GE.MY(OLDX,1).AND. * OLDY.LE.MY(OLDX,2))) GOTO 5005 WRITE(2,1) DOT PCTR=PCTR+1 P(PCTR,1)=OLDX P(PCTR,2)=OLDY 5005 CONTINUE JX=OLDX LASTPL = 1 ! OF LINE - LAST CHAR PLOTTED DO 5020 I=1,KX ! MOVE KX TIMES IN X DIRECTION IY = TY ! INTEGER LAST Y POSITION IF (DX.GT.0) JX = JX + 1 IF (DX.LT.0) JX = JX - 1 IF (DX.GT.0) WRITE(2,1)RIGHT ! MOVE TO THE RIGHT IF (DX.LT.0) WRITE(2,1)LEFT ! MOVE TO THE LEFT TY = TY + INCREM ! INCREMENT CURRENT Y POSITION JY = TY ! INTEGER CURRENT Y POSITION IY=JY-IY ! DO WE NEED TO MOVE IN Y IF (IY.EQ.0) GOTO 5010 ! NO - BRANCH IF (IY.EQ.1) WRITE(2,1) DOWN ! YES - MOVE DOWN IF (IY.EQ.-1) WRITE(2,2) UP ! YES - MOVE UP 5010 IF (JY.GE.MY(JX,1).AND.JY.LE.MY(JX,2)) GOTO 5020 WRITE(2,1) DOT PCTR=PCTR+1 P(PCTR,1)=JX P(PCTR,2)=JY 5020 CONTINUE ! LOOP TILL DONE GOTO 9999 ! ALL DONE - GO BACK C C LINE IS MORE VERTICAL THAN HORIZONTAL HERE C 5500 KY=IABS(DY) ! NUMBER OF Y MOVES TO MAKE IF (KY.EQ.0) GOTO 9999 ! DON'T NEED TO MOVE AT ALL INCREM = FLOAT(DX)/IABS(DY) ! X MOVE FOR EVERY 1 Y MOVE TX = OLDX + 0.5 ! INITIAL X POSITION IF (LASTPL.EQ.1.OR.(OLDY.GE.MY(OLDX,1).AND. * OLDY.LE.MY(OLDX,2))) GOTO 5505 WRITE(2,1) DOT PCTR=PCTR+1 P(PCTR,1)=OLDX P(PCTR,2)=OLDY 5505 CONTINUE LASTPL = 1 ! PLOTTED. LAST POSN PLOTTED. JY=OLDY DO 5520 I=1,KY ! MOVE VERTICALLY KY TIMES IX = TX ! INTEGER OLD X POSITION IF (DY.GT.0) JY=JY+1 IF (DY.LT.0) JY=JY-1 IF (DY.GT.0) WRITE(2,1)DOWN ! MOVE 1 POSITION DOWN IF (DY.LT.0) WRITE(2,2)UP ! MOVE 1 POSITION UP TX = TX + INCREM ! GET CURRENT X POSITION JX = TX ! INTEGER CURRENT X POSITION IX=JX-IX ! DID WE MOVE A FULL DOT? IF (IX.EQ.0) GOTO 5510 ! NO - BRANCH IF (IX.EQ.1) WRITE(2,1) RIGHT ! YES - MOVE RIGHT 1 POSITION IF (IX.EQ.-1) WRITE(2,1) LEFT ! YES - MOVE LEFT 1 POSITION 5510 IF (JY.GE.MY(JX,1).AND.JY.LE.MY(JX,2)) GOTO 5520 WRITE(2,1) DOT PCTR=PCTR+1 P(PCTR,1)=JX P(PCTR,2)=JY 5520 CONTINUE ! LOOP TILL DONE GOTO 9999 ! GO RETURN C ============================================================================ C C SUBROUTINE RETURN SECTION C C ============================================================================ 9999 OLDX = X ! REMEMBER CURRENT POSITION OLDY = Y 10000 IF (HIDDEN.EQ.0) RETURN IF (PCTR.EQ.0) RETURN DO 10001 I=1,PCTR ! MOVE HORIZON IX=P(I,1) IY=P(I,2) IF (IY.LT.MY(IX,1)) MY(IX,1)=IY IF (IY.GT.MY(IX,2)) MY(IX,2)=IY 10001 CONTINUE RETURN ! RETURN TO CALLER END