The film to be generated is a circle which moves from left to right across the screen at constant speed. For simplicity the complete display area is defined as a region having units 0 to 50 in both the X and Y directions. The circle moves from X = 1 to X = 50 in 50 frames.
DO 20 I = 1, 50 XX = I CALL SETXY (XX, 25.0) CALL UPDX (1.0) DO 10 J = 1, 64 X = COS(J*PI/32.0)+XX Y = SIN(J*PI/32.0)+25.0 CALL TOXY (X,Y) 10 CONTINUE CALL ADVFLM 20 CONTINUE
The major inefficiency here is the recalculation of COS and SIN for 64 different values each time the circle is generated.
The circle is defined as a file consisting of only relative line drawing commands:
CALL STDF(ANAME('CIRCLE')) CALL UPDX (1.0) OX = 1.0 OY = 0.0 DO 10 J 1, 64 X = COS(J*PI/32.0) Y = SIN(J*PI/32.0) CALL TODXY (X-OX, Y-OY) OX = X OY = Y 10 CONTINUE CALL UPDXY (-1.0, 0.0) CALL FIDF (1.0)
The circle is generated under the assumption that the position of the centre is the display position on entry. The display position is not changed by the routine. Generating the film required would then be:
CIRCLE = ANAME('CIRCLE') DO 20 I = 1, 50 X = I CALL SETXY (X, 25.0) CALL DRAW (CIRCLE) CALL ADVFLM 20 CONTINUE
This form might well be adopted if a number of circles of the same size were used at different positions on the display area. Note the use of a FORTRAN real variable to avoid recalculating ANAME.
The following two routines will set up CIRCLE as a display routine.
SUBROUTINE CIRCLE(X,Y) DIMENSION A(2) A(1)=X A(2)=Y IF(IDSTST(82.0,A)) 2,1,2 1 CALL DSPF82(A) 2 RETURN END SUBROUTINE DSPF82(A) DIMENSION A(2) PI=3.1415926 CALL SETXY(A(1),A(2)) CALL UPDX (1.0) OX=1.0 OY=0.0 DO 10 J=I,64 X=COS(J*PI/32.0) Y=SIN(J*PI/32.0) CALL TODXY(X-OX,Y-OY) OX=X OY=Y 10 CONTINUE CALL UPDXY(-I.O,O.O) RETURN END
Then a possible use of this display routine would be inside a file:
CALL NEWDSP(ANAME('CIRCLE'),2.0,82.0) XI=ANAME ('X1') YI=ANAME ('Y1 ') CALL STDF(ANAME('CIRX')) CALL CIRCLE (PRI (X1),PR2(Y1)) CALL FIDF(I.O)
This file would be very much shorter than that used in Section 12.2, and index variables have been introduced to set the initial position.
Index variables are used to replace the multiple calls of TODXY which would be stored. Again, FORTRAN real variables are used to minimise the use of ANAME.
CALL STDF (ANAME('CIRCLE')) CALL UPDX (1.0) Z = PI/32.0 OX = ANAME ('OX') OY = ANAME ('OY') X = ANAME ('X' ) Y = ANAME ('Y' ) T = ANAME ('T ') T1 = ANAME ('T1' ) XCNT = ANAME ('XCNT') CALL LOAD (OX,1.0) CALL LOAD (OY,0.0) CALL LOAD (XCNT,1.0) CALL WHILE (PR1(XCNT),'LE',64.0) CALL BEGINS CALL LOAD (T,PR2(XCNT)) CALL MPY (T,Z) CALL COSX (X,PR2(T)) CALL SINX (Y,PR2(T)) CALL LOAD (T,PR2(X)) CALL SUB (T,PR2(OX)) CALL LOAD (T1,PR2(Y)) CALL SUB (T1,PR2(Y)) CALL TODXY (PR1(T),PR2(T1)) CALL ADD (XCNT,I.O) CALL LOAD (OX,PR2(X)) CALL LOAD (OY,PR2(Y)) CALL ENDS CALL UPDXY (-1.0,0.0) CALL FIDF (1.0)
This will cause fewer orders to be stored, although the code appears longer. The same sequence of orders in Section 12.2 will generate the required film.
Using the file CIRCLE as before, the following two routines can be used:
XX = ANAME ('XX' ) SQ1 = ANAME ('SQ1') SQ2 = ANAME ('SQ2') CALL STDF (SQ2) CALL SETXY (PR1(XX),25.0) CALL DRAW (ANAME('CIRCLE')) CALL ADVFLM CALL REPEAT CALL FIDF (1.0) CALL STDF (SQ1) CALL LOAD (XX,1.0) CALL WHILE (PR1(XX), 'LE',50.0) CALL BEGINS CALL ADVFLM CALL ADD (XX,1.0) CALL ENDS CALL STOPSQ CALL FIDF (1.0)
and executed by:
CALL ADSQLG (SQ1,0.0,0.0) CALL DRAW (SQ2)
The complete source file for immediate execution would be:
MASTER CIRCLEMOVE C--- INITIALISE SPROGS COMMON CALL STSPR C--- SET UP REGION CHAIN CALL RGLIM (1,0,0.0,0.0,100.0,100.0) CALL RGPRM (1.0,0.0,0.0,1.0,0.0,0.0) CALL RGPLIM (1.0,0.0,0.0,1023.0,1023.0,0.0) C--- SELECT OUTPUT CALL DVOUT (2.0) C--- SELECT REGION CALL REGION (1.0) C--- DRAW CIRCLE PI = 3.1415926 DO 20 I = 1,50 XX = I CALL SETXY (XX,25.0) CALL UPDX (1.0) DO 10 J = 1,64 X = COS (J*PI/32.0)+XX Y = SIN (J*PI/32.0)+25.0 CALL TOXY (X,Y) 10 CONTINUE CALL ADVFLM 20 CONTINUE C--- FINISH CALL ENDSPR STOP OK END FINISH
If this is stored in file MYSOURCE, say, the appropriate simple macro call would be:
SPROGS *CR MYSOURCE
which would compile and run the job using work files for output, BROADCAST to the MOP job issuing the macro (if one exists) and list the monitor file, except for the commands.
As another example, the following macro call will save all the lineprinter listings in a file and ignore the monitor file:
SPROGS *CR MYSOURCE,*LP MYLIST1,#LP0 MYLISTl,EJ(NONE)
Note that the use of the SPROGS macro will generate a job with a predefined title (depending on the job issuing the macro). In order to run more than one job at once, a user must use:
RUNJOB JOBNAME, :MACROS.SPROGS,parameterlist
so that unique names may be given. (In the above, parameterlist refers to the list of SPROGS parameters available, just as in the previous call.) If RUNJOB is issued from a MOP terminal, a BROADCAST can be forced by using the parameter:
MOPEJ NAMEOFMOPJOB
Full details of the macro are given in Appendix 12.
High level routines, consisting of SPROGS display routines inside FORTRAN subroutines, can be constructed. However, since WHILE can only be used inside a file definition, two versions of such routines are required if repeated saving of commands is to be avoided. The following routine will provide a wipe from one picture file to another over a given number of frames.
It is included to show how an animation effect might be produced. In FORTRAN, it looks very cumbersome, but the example is repeated in the next Chapter, which deals with the preprocessor, to show the power of that system.
SUBROUTINE WIPE (A) DIMENSION A (4) C A (1) is the first file, A (2) the second C A (3) is the number of frames C A (4) is the number of a spare region C index variable names XP = ANAME ('XP') XMINR = ANAME ('XMINR') YMINR = ANAME ('YMINR') XMAXR = ANAME ('XMAXR') YMAXR = ANAME ('YMAXR') SW = ANAME ('SW') XCNT = ANAME ('XCNT') XLIM = ANAME ('XLIM') C save current region settings CALL RDBASE (SW) CALL RDPLIM (XP,XMINR,YMINR,XMAXR,YMAXR) C - - insert a new region in the chain CALL RGPLIM (-1.0,A(4),0.0,0.0,1023.0,1023.0) CALL RGPRM (A(4),0.0,0.0,1.0,0.0,PR6(SW)) CALL RGPRM (-1.0,-1.0,-1.0,-1.0,-1.0,0.0) C - - set frame counter CALL LOAD (XCNT,0.0 ) C - - loop for each frame CALL WHILE (PR1(XCNT), 'LE' ,A(3)) CALL BEGINS C use spare region to split current picture into two parts, C part of first file and part of second. CALL LOAD (XLIM,A(3)) CALL SUB (XLIM,PR2(XCNT)) CALL DVD (XLIM,A(3)) CALL LOAD (XSTP,PR2(XMAXR)) CALL SUB (XSTP,PR2(XMINR)) CALL MPY (XSTP,PR2(XLIM)) CALL ADD (XSTP,PR2(XMINR)) CALL MPY (XLIM,1023.0) C two pictures CALL RGLIM (A(4),0.0,0.0,PR4(XLIM),1023.0) CALL RGPLIM (A(4),PR2(XP),PR3(XMINR),PR4(YMINR),PR5(XSTP),PR6(YMAXR)) CALL DRAW (A( I)) CALL RGLIM (A(4),PR2(XLIM),O.O,1023.0,1023.0) CALL RGPLIM (A(4),PR2(XP),PR3(XSTP),PR4(YMINR),PR5(XMAXR),PR6(YMAXR)) CALL DRAW (A(2)) CALL ADD (XCNT,1.0) CALL ADVFLM CALL ENDS C reset region chain CALL RGPLIM (-1.0,PR2(XP),PR3(XMINR),PR4(YMINR),PR5(XMAXR),PR6(YMAXR)) CALL RGPRM (-1.0,-1.0,-1.0,-1.0,-1.0,PR6(SW)) RETURN END