C .R FORTRAN C *DK1:CRFWAR=DK1:CRFWAR C .R LINK C *DK1:CRFWAR=DK1:CRFWAR,DK:VTLIB,SYSLIB/F/B:1200 C C C*****FORTRAN RT-11 SPACEWAR C C C THIS SOFTWARE IS FURNISHED TO THE NON-PURCHASER C UNDER LICENSE FOR USE ON A DECLAB 11/40. IT CAN BE C COPIED TO YOUR HEART'S CONTENT FOR USE ON ANY EQUIVALENT C HARDWARE CONFIGURATION. DEC ASSUMES NP RESPONSIBILITY C FOR THE USE OR RELIABILITY OF THIS SOFTWARE ON EQUIPMENT C NOT SUPPLIED BY DEC. C C C*****ACKNOWLEDGEMENTS AND KUDOES ARE DUE MARIO DE NOBILI C*****AND HENRY MAURER FOR THEIR GUIDING INFLUENCE IN THE C*****EVOLUTION OF THIS PROGRAM. ANY QUESTIONS REGARDING C*****ALGORITHMS, DESIGN, PROCEDURES, BUGS, ETC., MUST C*****BE REFERRED TO MARIO DE NOBILI. C C*****G. W. DULANEY, LOP, MARLBOROUGH COUNTRY, JAN., 1975. C C*****REQUIRES F4GT,SYSLIB DIMENSION IDBF(750) DIMENSION AST1(20),AST2(20),SUN(16),M(20),INTP(20),ITRP(2) DIMENSION SND(2),CSD(2),NTRP(2),MPTR(4),KTH(2) DIMENSION SNA(2),CSA(2),VX(20),VY(20),X(20),Y(20) DIMENSION S1(10),S2(10) INTEGER IPHOT(2),LPTX(2),LTX(2) INTEGER TT,R,H INTEGER ISCA1(2),ISCA2(2) EQUIVALENCE (NTRP(1),NTRP1),(NTRP(2),NTRP2),(KTH(1),KTH1), X (KTH(2),KTH2),(M(1),M1),(M(2),M2),(ITRP(1),ITRP1), X (ITRP(2),ITRP2) EQUIVALENCE (LTX1,LTX(1)),(LTX2,LTX(2)) EQUIVALENCE (LPTX1,LPTX(1)),(LPTX2,LPTX(2)) C*****COORD'S FOR ASTEROIDS AND SUN DATA S1/10*0.0/ DATA S2/10*0.0/ DATA AST1/6.,-6.,6.,3.,0.,6.,6.,3.,-6.,6.,-6.,0., X -6.,3.,-3.,-9.,-6.,-6.,9.,0./ DATA AST2/-6.,-6.,9.,-2.,6.,8.,-1.,5.,-5.,4.,-3.,-3.,-3.,3., X -6.,-6.,3.,-3.,6.,0./ DATA SUN/6.,-18.,6.,18.,18.,6.,-18.,6.,-6.,18.,-6., X -18.,-18.,-6.,18.,-6./ C*****CONSTANTS FOR ANGLES, SHIP SIZE, TORPEDOES, GRAVITY, ETC. DATA G,NT,TD,TV,R1,STH,ISC1,ISC2/15.,50,25.,5.,32.,.025,0,0/ DATA GGG/.06/ DATA LPTXI,NPT/48,10/ DATA MRGN,TT,C,S,SND,CSD/14,500,.99619,.08716,.3125,.53125, X .94992,.84722/ DATA Y,X,VX,VY/20*620.,60*0./ C P=3.14159/36 C C=COS(P) C S=SIN(P) C*****SND=SIN(DELTA) AND CSD=COS(DELTA) C SND(1)=10/R1 C CSD(1)=SQRT(1-SND(1)**2) C SND(2)=17/R1 C CSD(2)=SQRT(1-SND(2)**2) C C WRITE(7,171) 171 FORMAT('$TYPE - ') ICRFG=0 172 I=ITTINR() IF (I.EQ.0)GO TO 172 IF (I.EQ.71)ICRFG=1 IF (I.NE.10)GO TO 172 IF (ICRFG.EQ.0)GO TO 179 C C***** GET NEW GRAVITY VALUES C WRITE(7,173) READ(7,178)G WRITE(7,174) READ(7,178)GGG WRITE(7,175) READ(5,178)TV WRITE(7,176) READ(7,177)LPTXI 176 FORMAT('$ENTER PHOTON DELAY - ') 177 FORMAT(I10) 178 FORMAT(F20.0) 173 FORMAT('$ENTER GRAVITY VALUE (10 TO 20) - ') 174 FORMAT('$ENTER INITIAL VELOCITY (.01 TO .1) - ') 175 FORMAT('$ENTER TORPEDO VELOCITY (1. TO 10.) - ') 179 CONTINUE CALL INIT(IDBF,740) C C C*****BEGIN WITH INTRO MESSAGE. CALL APNT(350.,750.,0,-8) CALL TEXT('S P A C E W A R ! ! (CRF)',2) CALL RDOT(0.,0.,0,-7,-1) CALL TEXT('YOU ARE ABOUT TO BEGIN YET ANOTHER COMPUTERIZED ', X 'VERSION OF',1,'SPACEWAR. ONLY HERE, IT IS RUNNING ON A ', X 'STANDARD MINICOMPUTER',1,'USING FORTRAN IV EXCLUSIVELY!!.',2, X 'IT IS THE OUTSTANDING EFFICIENCY OF RT-11 FORTRAN AND THE', X ' DECLAB 11/40 ',1,'HARDWARE WHICH ALLOW THE NUMEROUS') CALL TEXT(' CALCULATIONS TO BE PERFORMED',1,'ON THE FLY.',2) CALL TEXT(' SHIP #1, THE LARGER IS CONTROLLED BY MEANS', X ' OF THE CONSOLE SWITCHES.',1, X 'SWITCH 11 CONTROLS THRUST, SWITCH 10, CLOCKWISE ROTATION',1, X 'SWITCH 12 COUNTERCLOCKWISE ROTATION, AND SWITCH 15 FIRES',1, X 'TORPEDOES',2) CALL TEXT (' SHIP #2 IS CONTROLLED BY MEANS OF THE ' , X 'CONSOLE SWITCHES.',1, X 'SWITCH 1 CONTROLS THRUST, SWITCH 0, CLOCKWISE ROTATION',1, X 'SWITCH 2 COUNTERCLOCKWISE ROTATION, AND SWITCH 15 FIRES',1, X 'TORPEDOES',2) CALL TEXT(' TO CARRY ON WITH SUN TYPE "Y" CARRIAGE RETURN',1, X 'ELSE JUST CARRIAGE RETURN.') CALL TEXT(3,'NOTE: EACH SHIP HAS JUST BEEN FITTED WITH A NEW',1, X 'HIGH SPEED PHOTON TORPEDO SYSTEM. TEN ADDITIONAL HIGH SPEED',1, X 'TORPEDOES MAY BE FIRED BY SWITCH REGISTER BIT 14 FOR SHIP 1,',1, X 'AND 4 FOR SHIP 2. UNFORTUNATELY, A HEATING PROBLEM',1) CALL TEXT('IN THE FIRING MECHANISM FORCES A CERTAIN TIME,',1, X 'ABOUT 2 SECONDS, BETWEEN EACH TORPEDO.') C C C*****WAIT FOR KEYBOARD CHARACTER C IF IT IS 'Y' THEN WE HAVE SUN, OTHERWISE LOOP FOR 'LF' C ISCRF=0 1 I=ITTINR() IF (I.LT.0)GOTO 1 IF (I.EQ.66)ISCRF=2 IF (I.EQ.89)ISCRF=1 IF (I.NE.10)GO TO 1 IF (ISCRF.EQ.0)GGG=GGG/2. C C C C CC*****SET UP FIGR'S FOR SUN, SHIPS, AND ASTEROIDS. CALL INIT(IDBF,300) CALL APNT(10.,760.,0,-4) CALL DPTR(ISCP1) CALL TEXT('WINS 0') CALL APNT(890.,760.,0,-4) CALL DPTR(ISCP2) CALL TEXT('WINS 0') CALL APNT(11.,14.,0,-4,0,3) CALL VECT(1000.,0.) CALL VECT(0.,690.) CALL VECT(-1000.,0.) CALL VECT(0.,-690.) CALL APNT(350.,755.,0,-5,0,1) CALL TEXT('RT-11 FORTRAN SPACEWAR') CALL APNT(50.,710.,0,-5,-1) CALL TEXT('SHIP 1: FUEL ') CALL RDOT(0.,0.) C*****SAVE ADDRESSES FOR LATER UPDATES. MPTR FOR Y VECTORS. CALL DPTR(I) MPTR(1)=I+2 CALL LVECT(0.,50.) CALL APNT(250.,710.,0,-5) CALL TEXT('TORPS ') CALL RDOT(0.,0.) CALL DPTR(I) MPTR(2)=I+2 CALL LVECT(0.,50.) CALL APNT(650.,710.,0,-5) CALL TEXT('SHIP 2: FUEL ') CALL RDOT(0.,0.) CALL DPTR(I) MPTR(3)=I+2 CALL LVECT(0.,50.) CALL APNT(850.,710.,0,-5) CALL TEXT('TORPS ') CALL RDOT(0.,0.) CALL DPTR(I) MPTR(4)=I+2 CALL LVECT(0.,50.) CALL APNT(506.,378.,0,-7) IF (ISCRF.EQ.1)CALL FIGR(SUN,16,0,6) IF (ISCRF.EQ.2)CALL FIGR(SUN,16,0,7,1) C*****KEEP DISPLAY FILE POINTERS IN INTP. C*****POINTERS TO X COORD'S. CALL DPTR(I) INTP(1)=I+1 CALL APNT(512.,384.,0,-5,-1) CALL FIGR(S1,10) CALL DPTR(I) INTP(2)=I+1 CALL APNT(512.,384.,0,-5) CALL FIGR(S2,10) CALL DPTR(I) INTP(3)=I+1 CALL APNT(662.,384.,0,-4) CALL FIGR(AST1,20) CALL DPTR(I) INTP(4)=I+1 CALL APNT(362.,384.,0,-4) CALL FIGR(AST2,20) C*****SAVE TORPEDO POINTERS DO 50 J=5,20 CALL DPTR(I) INTP(J)=I+1 CALL APNT(512.,1025.) 50 CALL RDOT(0.,0.,0,8) C***** STRT RANDOM NUMBER GENERATOR IRAND1=0 IRAND2=0 DO 10 I=1,10 10 RAND=RAN(IRAND1,IRAND2) C*****BEGIN START OF MAIN LOOP, RETURN TO HERE TO RESTART. C*****SNA, CSA ARE SIN & COS FOR ANGLE OF ATTACK MINUS PI. C*****NOSE OF SHIP IS ORIGIN OF CENTER LINE VECTOR POINTING C*****TOWARD STERN. C C*****SET UP SHIPS 240 SNA(1)=0 CSA(1)=1 SNA(2)=0 CSA(2)=-1 C****** GENERATE RANDOM STARTING POSITION X(1)=1000.*(RAN(IRAND1,IRAND2)-0.5) Y(1)=690.*(RAN(IRAND1,IRAND2)-0.5) X(2)=1000.*(RAN(IRAND1,IRAND2)-0.5) Y(2)=1000.*(RAN(IRAND1,IRAND2)-0.5) VX(1)=-50.*GGG VY(1)=0 VX(2)=-VX(1) VY(2)=-VY(1) M1=1 M2=1 C*****INDIVIDUAL TORP & THRUST COUNTERS WILL DECR. TO 0 NTRP1=NT+NPT NTRP2=NT+NPT KTH1=TT KTH2=TT C*****SET UP ASTEROIDS M(3)=1 M(4)=1 X(3)=150 Y(3)=0 X(4)=-X(3) Y(4)=-Y(3) VX(3)=0 VY(3)=80.*GGG VX(4)=-VX(3) VY(4)=-VY(3) L1=0 NTX=4 LTX(1)=0 LTX(2)=0 H=0 L=-2 C*****PUT TORP'S OUT OF PICTURE DO 250 I=5,20 250 M(I)=-1 C*****ASSIGN EACH PLAYER 3 PHOTON TORPEDOES IPHOT(1)=NPT IPHOT(2)=NPT LPTX(1)=0 LPTX(2)=0 C C********* PLACE WIN TOTALS ON SCREEN ENCODE(4,223,ISCA1)ISC1 ENCODE(4,223,ISCA2)ISC2 223 FORMAT(I4) DO 224 IS=1,2 IDBF(ISCP1+IS+2)=ISCA1(IS) 224 IDBF(ISCP2+IS+2)=ISCA2(IS) C C*****BEGIN REPETITIVE LOOP C*****FIRST, LOOP TO CHECK COLLISIONS FOR ALL & RESET POSITIONS C*****IF HAVE A COLLISION, M GOES -1 WHICH IS SERVICED BELOW. 320 DO 550 J=1,19 C*****J=1 FOR SHIP 1, =2 FOR SHIP 2, =3 FOR ASTEROID 1, C =4 FOR ASTEROID 2, AND =5-19 FOR TORPEDOES. C*****CHECK SUN'S PROXIMITY XJ=X(J) YJ=Y(J) DO=XJ*XJ+YJ*YJ G1=G/DO IF (M(J).GT.0)GO TO 145 IF (J.LE.2)GO TO 146 145 IF(DO.LT.625..AND.ISCRF.NE.0)GOTO 641 C*****NOW CHECK WALL COLLISIONS IF (J.GT.4)GO TO 150 146 IF(XJ.GT.500.)XJ=XJ-1000. IF(XJ.LT.-500.)XJ=XJ+1000. IF(YJ.GT.320)YJ=YJ-690. IF(YJ.LE.-370.)YJ=YJ+690. IF (M(J).LE.0)GO TO 510 GO TO 350 150 IF(XJ.GT.500.)GOTO 610 IF(XJ.GT.-500.)GOTO 620 610 VX(J)=-VX(J) GOTO 641 620 IF(YJ.LT.-370.)GOTO 640 IF(YJ.LT.320.)GOTO 350 640 VY(J)=-VY(J) 641 M(J)=-1 GOTO 510 C*****LOOP CHECKS PROXIMITY TO OTHER BODIES 350 DO 420 I=J+1,20 IF (M(I).LE.0)GOTO 420 IDX=X(I)-XJ IF(IDX.GT.MRGN.OR.IDX.LT.-MRGN)GOTO 420 IDY=Y(I)-YJ IF(IDY.GT.MRGN.OR.IDY.LT.-MRGN)GOTO 420 M(I)=-1 M(J)=-1 420 CONTINUE IF(M(J).GT.0)GOTO 520 510 IF (J.GT.2)GOTO 550 C*****INCLUDE SUN'S GRAVITY THEN REPOSITION 520 IF (ISCRF.EQ.0)GO TO 549 VX(J)=VX(J)-G1*XJ VY(J)=VY(J)-G1*YJ 549 X(J)=XJ+VX(J) Y(J)=YJ+VY(J) 550 CONTINUE C*****READ TORPEDO SWITCHES C********* ICT=IPEEK("177570) C********* ITRP1=ICT-(ICT/2)*2 C***CRF*** ITRP2=ICT/32767 C C ICRF=IPEEK("177570) IF (LTX1.LT.12)GO TO 143 C BIT 15 IS SLOW TORP (<0) AND 14 IS FAST TORP ITRP1=ICRF.AND."140000 143 IF (LTX2.LT.12)GO TO 144 C BIT 5 SLOW, BIT 4 FAST ITRP2=ICRF.AND."60 IF(ITRP2.GT."20) ITRP2=-1 144 CONTINUE C C*****LARGE LOOP FOR SHIPS WHICH: C 1. CHECKS FOR CRASH C 2. LAUNCHES TORP'S(SR 15 & 0) C 3. ADDS THRUST(POTS 0 & 2) C 4. ROTATES SHIPS(POTS 1 & 3) DO 900 J=1,2 I=J*2-1 IDBF(MPTR(I))=KTH(J)/10 IDBF(MPTR(I+1))=NTRP(J) SNAJ=SNA(J) CSAJ=CSA(J) IF (M(J).GE.0)GOTO 645 C*****A SHIP HIT SOMETHING. COUNT IT OUT. H=H+1 IF(H.GT.100)GOTO 990 C*****SET UP PENTACLE AS CRASH SYMBOL X5=23. Y5=-69. X6=-59. Y6=43. X7=71. Y7=0. X0=-59. Y0=-43. X8=23. Y8=69. R=1 GOTO 880 C*****GO IF IF NO TORP'S 645 IF (ITRP(J).EQ.0)GOTO 660 IF (NTRP(J).EQ.0)GOTO 660 C*****RING BUFFER THE TORP'S. DROP DEAD THEN OLD ONES. IF (NTX.GE.19)NTX=4 647 NTX=NTX+1 IF (M(NTX).EQ.-1)GO TO 649 IF(NTX.LT.19)GOTO 647 NTX=5 649 TVM=TV IF (ITRP(J).LT.0)GO TO 665 C** FIRE PHOTON TORP. IF (LPTX(J).GT.0)GO TO 660 IPHOT(J)=IPHOT(J)-1 IF (IPHOT(J).LT.0)GO TO 660 LPTX(J)=LPTXI TVM=TV*4. 665 M(NTX)=1 X(NTX)=X(J)-TD*CSAJ Y(NTX)=Y(J)-TD*SNAJ VX(NTX)=VX(J)-TVM*CSAJ VY(NTX)=VY(J)-TVM*SNAJ NTRP(J)=NTRP(J)-1 LTX(J)=0 C*****GET THRUST POT READING 660 ITRP(J)=0 IC=0 IF(J.EQ.1)IC=2 D=JPOT(IC) IF(D.LT.2250)GOTO 650 IF(KTH(J).LT.0)GOTO 650 D=-STH KTH(J)=KTH(J)-1 VX(J)=VX(J)+CSAJ*D VY(J)=VY(J)+SNAJ*D C*****COMPUTER NEW CENTER LINE VECTOR 650 Y0=R1*SNAJ X0=R1*CSAJ R=0 S3=S C*****ROTATION IS REQUIRED ONLY ONCE IN TWO PASSES IF(L.GT.1)GOTO 850 C*****GET ROTATION POT R=JPOT(IC+1)+1 C*****L<0 SETS UP SHIPS FIRST TIMES THRU. IF (L.LT.0)GOTO 730 IF(R.LT.1850)GOTO 730 IF(R.GT.2250)GOTO 725 R=0 GOTO 850 C*****FOR CLOCKWISE ROTATION INVERT SIN 725 S3=-S C*****USE OLD SUM-OF-ANGLES RULES 730 SNA(J)=SNAJ*C+CSAJ*S3 CSA(J)=CSAJ*C-SNAJ*S3 C*****X(J)=X0*COS(DELTA)-Y0*SIN(DELTA) C*****Y(J)=Y0*COS(DELTA)+X0*SIN(DELTA) C*****WHERE X0,Y0 DEFINE VECTOR FOR CENTER LINE OF SHIP C*****AND DELTA IS ANGLE OF SIDES FROM THAT VECTOR C*****ROTATE CENTER LINE VECTOR Y0=R1*SNA(J) X0=R1*CSA(J) C*****COMPUTE PORT (LEFT) SIDE OF SHIP (NOTE NEGATIVE ANGLE) CSDJ=CSD(J) SNDJ=SND(J) X5=CSDJ*X0+Y0*SNDJ Y5=CSDJ*Y0-X0*SNDJ C*****THEN STERN VECTOR C X6=CSDJ*X0-Y0*SNDJ-X5 C Y6=CSDJ*Y0+X0*SNDJ-Y5 X6=-2.*Y0*SNDJ Y6=2.*X0*SNDJ C*****AND RETURN TO ORIGIN DRAWING X7=-X5-X6 Y7=-Y5-Y6 C*****SET UP VARIABLE LENGTH FLAME VECTOR STERNWARD C*****IF THRUST IS ON (D IS NEGATIVE). 850 Z=L Z=Z/4. IF(D.GE.0)Z=0 X8=Z*X0 Y8=Z*Y0 C*****RESET ROTATION LOOP COUNTER 880 L=L+1 IF(L.GT.4)L=0 C*****RESET SHIP ANGLE OF ATTACK 920 IF(J.EQ.2)GOTO 980 CALL APUT(S1(9),X8) CALL APUT(S1(10),Y8) IF (R.EQ.0)GOTO 900 CALL APUT(S1(1),X5) CALL APUT(S1(2),Y5) CALL APUT(S1(3),X6) CALL APUT(S1(4),Y6) CALL APUT(S1(5),X7) CALL APUT(S1(6),Y7) CALL APUT(S1(7),X0) CALL APUT(S1(8),Y0) GOTO 900 980 CALL APUT(S2(9),X8) CALL APUT(S2(10),Y8) IF (R.EQ.0)GOTO 900 CALL APUT(S2(1),X5) CALL APUT(S2(2),Y5) CALL APUT(S2(3),X6) CALL APUT(S2(4),Y6) CALL APUT(S2(5),X7) CALL APUT(S2(6),Y7) CALL APUT(S2(7),X0) CALL APUT(S2(8),Y0) 900 CONTINUE C*****RESET TORP FIRING COUNTER LTX1=LTX1+1 LTX2=LTX2+1 C*****RESET PHOTON TORP. FIRING COUNTER LPTX1=LPTX1-1 LPTX2=LPTX2-1 C*****LOOP RESETS ALL POSITIONS DO 940 I=1,19 IDCRF=0 IF (M(I).GE.0)GOTO 930 C*****SHIP HAD A COLLISION OR IS INACTIVE AST. OR TORP(OFF SCREEN) IF(I.LT.3)GOTO 930 IDCRF=I*10 X(I)=0 Y(I)=620 VX(I)=0 VY(I)=0 930 IDBF(INTP(I))=X(I)+512.5+IDCRF IDBF(INTP(I)+1)=Y(I)+384.5 940 CONTINUE C*****IF BOTH SHIPS OUT OF FUEL OR TORPS, COUNT DOWN IF(NTRP1+NTRP2.LT.2)L1=L1+2 IF(KTH1+KTH2.LT.0)L1=L1+1 IF (L1.LT.300)GOTO 320 C*****SEE IF ANYBODY WON THE GAME 990 IF(M1.LT.0.AND.M2.GE.0)ISC2=ISC2+1 IF(M1.GE.0.AND.M2.LT.0)ISC1=ISC1+1 C*****NOW RESET AND START AGAIN GOTO 240 END FUNCTION JPOT(ICH) J=IPEEK("177570) IF (ICH.LE.1)GO TO 99 IF (ICH.EQ.3)GO TO 1 C BIT 11 THRUST J=(J.AND."4000) 10 JPOT=2260 IF (J.EQ.0)JPOT=2000 RETURN 1 CONTINUE C BIT 10 CLOCKWISE C BIT 12 COUNTER CLOCKWISE J1=(J.AND."2000) J2=(J.AND."10000) 11 IF(J1.NE.0) J1=1 IF (J2.NE.0)J2=1 JPOT=2000 IF (J1.GT.J2)JPOT=1000 IF (J2.GT.J1)JPOT=3000 RETURN C C COME HERE FOR SHIP 2 C 99 IF (ICH.EQ.1)GO TO 100 C BIT 1 THRUST J=J.AND."2 GOTO 10 100 CONTINUE C BIT 0 CLOCK C BIT 2 COUNTERCLOCK J1=(J.AND."1) J2=(J.AND."4) GOTO 11 END