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