From: Didier Morandi [Didier.Morandi.nospam@Free.fr] Sent: Wednesday, April 02, 2003 1:40 AM To: Info-VAX@Mvb.Saic.Com Subject: Re: The Space Invaders minute of the day: source C Video Terminal Space Invaders C C Originally written in C by Jude Miller, 1979, Cambridge. C Translated to FORTRAN-77 by Jonathan Boswell, July '81 C at the University of Virginia, Charlottesville, Virginia. C C Machine dependent subroutines are SLEEP, CLEAR, MOVE, SPECIAL_GRAPHIC, C and FUNCTION INCHAR. These subroutines are written for a VAX/VMS C operating system employing VT100 terminals. C PROGRAM INVADERS IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL DATA GAME,SCORES,BASES,DANGER,MAX_DANGER,MAX_BOMB_ROW,SLOW 1 /0,0,3,11,22,20,.FALSE./ CALL CLEAR CALL MOVE(5,0) TYPE*,'Attention: Alien invasion in progress!' TYPE* TYPE*,'Instructions: <1> to move the laser base left' TYPE*,' <2> to halt the laser base' TYPE*,' <3> to move the laser base right' TYPE*,' to fire a laser beam' TYPE*,' to quit' TYPE* TYPE*,' Type: <1> to play Bloodbath' TYPE*,' <2> to play We Come in Peace' TYPE*,' <3> to play Invasion of the Aliens' TYPE*,' <4> to play Invisible Alien Weasels' ACCEPT*,GAME CALL SPECIAL_GRAPHIC(.TRUE.) 1 CALL TABLEAU !Draw starting game tableau. CALL SLEEP('04.00') !Pause a few seconds. 2 CALL COMMAND !See if there's a command waiting. CALL BEAM !Update laser beam. CALL BASE !Slide laser base around. CALL BOMB !Drop alien bombs. CALL SHIP !Fly mystery ship across top of screen. CALL ADVANCE !Advance an alien. CALL ADVANCE !Advance another alien. IF (ALIENS_LEFT.EQ.0) GO TO 1 GO TO 2 END SUBROUTINE TABLEAU C Tableau draws the starting game tableau. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL CHARACTER*80 INIT_BARR(4) DATA INIT_BARR/ 1' lwwwwwwk lklklklk lklklklk 2 lwwwwwwk ', 3' lnnvvvvnnk lvnvvvvnvk lvnvvvvnvk 4 lnnvvvvnnk ', 5' tnu tnu tqu tqu tqu tqu 6 tnu tnu ', 7' mvj mvj mqj mqj mqj mqj 8 mvj mvj '/ CALL CLEAR CALL MOVE(0,0) CALL SEND('SCORE:') CALL SEND_INT(SCORES) CALL MOVE(0,18) CALL SEND('I N V A S I O N O F T H E A L I E N S !') CALL MOVE(0,70) CALL SEND('BASES:') CALL SEND_INT(BASES) C Initialize alien co-ords, display ! ALIENS_LEFT = 55 DO 20 J=0,4 CALL MOVE(DANGER-(2*J),0) DO 20 I=1,11 CALL DS_OBJ(((I+J).AND.1)+(2*(J/2))) CALL SEND(' ') ALIEN_ROW(11*J+I) = DANGER - (2*J) 20 ALIEN_COL(11*J+I) = 6*(I-1) ALIEN = 55 FLIP = .FALSE. FLOP = .FALSE. LEFT = .FALSE. C Initialize laser base position, velocity. BASE_ROW = 23 BASE_COL = 72 BASE_VEL = -1 BEAM_ROW = 0 CALL MOVE(BASE_ROW,BASE_COL) CALL DS_OBJ(7) C Initialize bomb arrays. (ROW = 0 implies empty) DO 30 I=1,MAX_BOMBS 30 BOMB_ROW(I) = 0 B = 0 FALLING_BOMBS = 0 C Initialize barricades. DO 40 I=MAX(1,DANGER-17),4 CALL MOVE(I+18,0) CALL SEND(INIT_BARR(I)) 40 BARR(I)=INIT_BARR(I) !String assignment, 1 to 80. DANGER=MIN(MAX_DANGER,DANGER+1) !Get ready for next set of aliens. C Initialize mystery ships. SHIP_VEL = 0 RETURN END SUBROUTINE SLEEP(TAG) C Set timer and wait for TAG seconds. TAG is a CHARACTER*5 string C of the form ##.##, which is the seconds, and hundredths of seconds. C To delay game for 5 seconds, TAG would be '05.00'. IMPLICIT INTEGER*4 (A-Z) EXTERNAL SS$_NORMAL DOUBLE PRECISION TIME CHARACTER DELTA_TIME*9,TAG*5 DELTA_TIME='0 ::'//TAG !Concatenate strings. RET_STAT=SYS$BINTIM(DELTA_TIME,TIME) !ASCII to binary time. IF(RET_STAT.NE.%LOC(SS$_NORMAL))STOP'BINTIM failed.' RET_STAT=SYS$SETIMR(,TIME,,) !Set timer, event flag 0. IF(RET_STAT.NE.%LOC(SS$_NORMAL))STOP'SETIMR failed.' RET_STAT=SYS$WAITFR(%VAL(0)) !Wait for flag 0 to be set. IF(RET_STAT.NE.%LOC(SS$_NORMAL))STOP'WAITFR failed.' RETURN END SUBROUTINE COMMAND IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL BYTE INCHAR,INPT IF(SLOW)CALL SLEEP('04.00') !Use all five characters. IF (GAME.EQ.1) THEN IF (BASE_COL.LE.1) BASE_VEL = 1 IF (BASE_COL.GE.72) BASE_VEL = -1 ENDIF INPT=INCHAR() !Take in character from keyboard. IF(INPT.EQ.' ')THEN IF (BEAM_ROW.EQ.0) BEAM_ROW = 23 RETURN ELSE IF(INPT.EQ.'Q'.OR.INPT.EQ.'q')THEN CALL HALT ENDIF IF(GAME.EQ.1)RETURN IF(INPT.LE.'3'.AND.INPT.GE.'1') BASE_VEL=INPT-ICHAR('2') RETURN END BYTE FUNCTION INCHAR() C Take in single character from terminal, but don't wait if C it isn't there. IMPLICIT INTEGER*4 (A-Z) INTEGER*2 TTIOSB(4) EXTERNAL IO$_READLBLK,IO$M_TIMED,IO$M_NOECHO EXTERNAL SS$_NORMAL,SS$_TIMEOUT CHARACTER*63 TERMINAL LOGICAL FIRST DATA FIRST/.TRUE./ IF(FIRST)THEN C Find out what terminal we're on. SSCODE=SYS$TRNLOG('TT',,TERMINAL,,,) IF(SSCODE.NE.%LOC(SS$_NORMAL))STOP'Translation failure.' C Assign channel. SSCODE=SYS$ASSIGN(TERMINAL,TT_CHAN,,) IF(SSCODE.NE.%LOC(SS$_NORMAL))STOP'Assignment failure.' FIRST=.FALSE. C Manufacture QIO command with NOECHO and TIMED modifiers. TIMED_IO = IOR(%LOC(IO$_READLBLK),%LOC(IO$M_TIMED)) TIMED_IO = IOR(TIMED_IO,%LOC(IO$M_NOECHO)) ENDIF C Read character from TT_CHAN into INCHAR with 0 timeout. 1 SSCODE=SYS$QIOW(%VAL(0),%VAL(TT_CHAN),%VAL(TIMED_IO) 1 ,TTIOSB,,,INCHAR,%VAL(1),%VAL(0),,,) IF(SSCODE.NE.%LOC(SS$_NORMAL))STOP'QIO argument error.' ERROR=TTIOSB(1) IF(ERROR.EQ.%LOC(SS$_TIMEOUT)) THEN INCHAR=0 RETURN ENDIF IF(ERROR.EQ.%LOC(SS$_NORMAL)) RETURN STOP'QIO return error.' END SUBROUTINE BASE C Move laser base left or right. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL OLD_COL=BASE_COL BASE_COL=BASE_COL+BASE_VEL IF (BASE_COL.LT.1) THEN BASE_COL = 1 ELSE IF (BASE_COL.GT.72) THEN BASE_COL = 72 ENDIF IF (BASE_COL.EQ.OLD_COL) RETURN CALL MOVE(BASE_ROW,BASE_COL) CALL DS_OBJ(7) RETURN END SUBROUTINE BEAM C Activate or advance the laser beam if required. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL C Display beam IF(BEAM_ROW.EQ.0)RETURN BEAM_ROW=MAX(BEAM_ROW-1,0) !Increment beam position. IF(BEAM_ROW.EQ.0)THEN !Erase beam, return. CALL MOVE(1,BEAM_COL) CALL SEND(' '//CHAR(8)//CHAR(10)//' ') RETURN ELSE IF(BEAM_ROW.EQ.21)THEN CALL MOVE(21,BEAM_COL) CALL SEND('x') ELSE IF(BEAM_ROW.EQ.22)THEN BEAM_COL = BASE_COL + 3 CALL MOVE(22,BEAM_COL) CALL SEND('x') ELSE CALL MOVE(BEAM_ROW,BEAM_COL) CALL SEND('x'//CHAR(8)//CHAR(10)//CHAR(10)//' ') ENDIF C Check for contact with an alien. DO 10 I=1,55 IF ((ALIEN_ROW(I).EQ.BEAM_ROW).AND.((ALIEN_COL(I)+1).LE.BEAM_COL) 1 .AND.((ALIEN_COL(I)+3).GE.BEAM_COL)) THEN C Contact! SCORES = SCORES+(I/22)+1 !Add points. CALL MOVE(0,7) CALL SEND_INT(SCORES) CALL SEND(CHAR(7)) !Ring the bell. CALL MOVE(BEAM_ROW+1,BEAM_COL) CALL SEND(' ') CALL MOVE(ALIEN_ROW(I),ALIEN_COL(I)) CALL DS_OBJ(6) !Erase beam and alien. BEAM_ROW=0 ALIEN_ROW(I)=0 !Clear beam and alien state. ALIENS_LEFT=ALIENS_LEFT-1 RETURN ENDIF 10 CONTINUE C Check for contact with a bomb. DO 20 I=1,MAX_BOMBS IF (BEAM_COL.NE.BOMB_COL(I).OR.BOMB_ROW(I).EQ.0)GO TO 20 IF(BEAM_ROW.EQ.BOMB_ROW(I).OR.BEAM_ROW-1.EQ.BOMB_ROW(I)) THEN CALL MOVE(BEAM_ROW,BEAM_COL) CALL SEND(' '//CHAR(8)//CHAR(10)//' ') BEAM_ROW = 0 CALL MOVE(BOMB_ROW(I),BEAM_COL) CALL SEND(' '//CHAR(7)) FALLING_BOMBS=FALLING_BOMBS-1 BOMB_ROW(I) = 0 RETURN ENDIF 20 CONTINUE C Check for contact with a barricade. IF ((BEAM_ROW.GE.19).AND.(BEAM_ROW.LE.22).AND. 1(BARR(BEAM_ROW-18)(BEAM_COL+1:BEAM_COL+1).NE.' ')) THEN CALL MOVE(BEAM_ROW,BEAM_COL) CALL SEND(' '//CHAR(8)//CHAR(10)//' '//CHAR(7)) BARR(BEAM_ROW-18)(BEAM_COL+1:BEAM_COL+1) = ' ' BEAM_ROW = 0 RETURN ENDIF C Check for contact with a mystery ship. I=SHIP_COL-SHIP_VEL IF (SHIP_VEL.NE.0.AND.BEAM_ROW.EQ.1.AND.BEAM_COL.GT.I 1.AND.BEAM_COL.LT.I+7) THEN C Contact! CALL MOVE(1,I) CALL SEND(CHAR(7)//' ') !Erase ship. SHIP_VEL = 0 SCORES = SCORES+SHIP_VAL/3 CALL MOVE(0,7) CALL SEND_INT(SCORES) ENDIF RETURN END SUBROUTINE BOMB C Advance the next active bomb. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL IF (FALLING_BOMBS.EQ.0) RETURN 10 B=B+1 IF (B.GT.MAX_BOMBS) B=1 IF (BOMB_ROW(B).EQ.0) GO TO 10 C Advance the bomb, check for hit, and display. BOMB_ROW(B)=BOMB_ROW(B)+1 IF (BOMB_ROW(B).EQ.23) THEN IF ((BOMB_COL(B).GT.BASE_COL).AND. 1 (BOMB_COL(B).LE.(BASE_COL+5))) THEN C The base is hit! BASES=BASES-1 CALL MOVE(0,76) CALL SEND_INT(BASES) C Make some noise, erase the base. CALL SEND(CHAR(7)//CHAR(7)//CHAR(7)) IF (BASES.EQ.0) CALL HALT CALL SLEEP('02.00') !Use all five characters. CALL MOVE(23,BASE_COL) CALL SEND(' ') BASE_COL = 72 BASE_VEL = -1 ENDIF !Bomb erased below. ENDIF IF((BOMB_ROW(B).GE.19).AND.(BOMB_ROW(B).LT.23).AND. 1(BARR(BOMB_ROW(B)-18)(BOMB_COL(B)+1:BOMB_COL(B)+1).NE.' ')) THEN C The bomb has hit a barricade. CALL MOVE(BOMB_ROW(B)-1,BOMB_COL(B)) CALL SEND(' '//CHAR(8)//CHAR(10)//' '//CHAR(7)) BARR(BOMB_ROW(B)-18)(BOMB_COL(B)+1:BOMB_COL(B)+1) = ' ' BOMB_ROW(B) = 0 FALLING_BOMBS=FALLING_BOMBS-1 RETURN ENDIF C Now display bomb in its new location. CALL MOVE(BOMB_ROW(B)-1,BOMB_COL(B)) CALL SEND(' '//CHAR(8)//CHAR(10)//'*') IF (BOMB_ROW(B).EQ.23) THEN !Erase bomb. FALLING_BOMBS=FALLING_BOMBS-1 BOMB_ROW(B) = 0 CALL SEND(CHAR(8)//' ') ENDIF RETURN END SUBROUTINE SHIP C Create or advance a mystery ship (maybe). IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL REAL RAN INTEGER*4 SEED DATA SEED/337733893/ IF (SHIP_VEL.EQ.0) THEN IF (RAN(SEED).LT..005) THEN C Create a mystery ship about once every minute. IF (RAN(SEED).LT..2) THEN SHIP_VEL = -1 SHIP_COL = 72 ELSE SHIP_VEL = 1 SHIP_COL = 1 ENDIF SHIP_VAL = 90 ENDIF ELSE C Update an existing mystery ship. CALL MOVE(1,SHIP_COL) IF (GAME.NE.4) THEN WHIRL=MOD(SHIP_COL,3) IF(WHIRL.EQ.0)THEN CALL SEND(' <--`> ') ELSE IF (WHIRL.EQ.1)THEN CALL SEND(' <-`-> ') ELSE CALL SEND(' <`--> ') ENDIF ENDIF SHIP_VAL=SHIP_VAL-1 SHIP_COL = SHIP_COL+SHIP_VEL IF (SHIP_COL.GT.72.OR.SHIP_COL.LT.1)THEN C Remove the mystery ship. CALL MOVE(1,SHIP_COL-SHIP_VEL) CALL SEND(' ') SHIP_VEL = 0 ENDIF ENDIF RETURN END SUBROUTINE ADVANCE C Advance the next alien. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL 10 ALIEN=ALIEN+1 IF (ALIEN .GT. 55)THEN IF (ALIENS_LEFT.EQ.0) RETURN ! check if done ! FLOP = .FALSE. IF (FLIP) THEN LEFT = .NOT.LEFT FLOP = .TRUE. ENDIF FLIP = .FALSE. ALIEN = 1 ENDIF I=ALIEN_ROW(ALIEN) IF(I.LE.0)GO TO 10 IF (I.GE.23) CALL HALT !Aliens have overrun base. IF (LEFT) THEN ALIEN_COL(ALIEN)=ALIEN_COL(ALIEN)-1 ELSE ALIEN_COL(ALIEN)=ALIEN_COL(ALIEN)+1 ENDIF J=ALIEN_COL(ALIEN) IF (J.EQ.0.OR.J.EQ.75) FLIP = .TRUE. CALL MOVE(I,J) IF (FLOP) THEN CALL DS_OBJ(6) ALIEN_ROW(ALIEN)=ALIEN_ROW(ALIEN)+1 I=ALIEN_ROW(ALIEN) CALL MOVE(I,J) ENDIF CALL DS_OBJ((ALIEN.AND.1)+2*((ALIEN-1)/22)) C Check for bomb release. IF ((GAME.EQ.1).OR.(GAME.EQ.2)) RETURN !Disable bombs. DO 50 I=ALIEN-11,0,-11 !Don't drop bombs on your own men. IF (ALIEN_ROW(I).NE.0) RETURN 50 CONTINUE IF (ALIEN_COL(ALIEN).GE.BASE_COL.AND.ALIEN_COL(ALIEN).LT.BASE_COL+3 1.AND.ALIEN_ROW(ALIEN).LE.MAX_BOMB_ROW) THEN DO 60 I=1,MAX_BOMBS IF (BOMB_ROW(I).EQ.0) THEN BOMB_ROW(I) = ALIEN_ROW(ALIEN) BOMB_COL(I) = ALIEN_COL(ALIEN) + 2 FALLING_BOMBS=FALLING_BOMBS+1 RETURN ENDIF 60 CONTINUE ENDIF RETURN END SUBROUTINE HALT C Game over processing. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL C Display the aliens if they were invisible. IF (GAME.EQ.4) THEN GAME = 3 !Remove the cloak of invisibility. DO 10 I=1,55 IF (ALIEN_ROW(I).NE.0) THEN CALL MOVE(ALIEN_ROW(I),ALIEN_COL(I)) CALL DS_OBJ((I.AND.1)+2*(I/22)) ENDIF 10 CONTINUE ENDIF DO 20 I=1,10 20 CALL SEND(CHAR(7)) CALL SLEEP('05.00') !Use all five characters. CALL SPECIAL_GRAPHIC(.FALSE.) CALL MOVE(23,0) CALL EXIT END SUBROUTINE SPECIAL_GRAPHIC(ON_OFF) LOGICAL ON_OFF BYTE TYP INTEGER*4 FLAG,RET_STAT RET_STAT=LIB$SCREEN_INFO(FLAG,TYP,,) IF(ON_OFF)THEN !Turn on special graphics mode. IF(TYP.EQ.64)THEN !We're in VT52 mode. CALL SEND(CHAR(27)//'F') ELSE IF(TYP.EQ.96.OR.TYP.EQ.110)THEN !We're in VT100/200 mode. TYPE* TYPE*,'I run faster in VT52 mode. To set, type' TYPE*,'SET TERM/VT52 (and that''s all)' TYPE*,'from DCL level. Otherwise, wait a moment.' TYPE* CALL SLEEP('10.00') !Use all five characters. CALL SEND(CHAR(27)//'(0') ELSE !We're on an unknown terminal. TYPE*,'Terminal type',TYP STOP'I only know how to address VT100''s and VT52''s.' ENDIF ELSE !Reset to ASCII mode. IF(TYP.EQ.64)THEN !Reset the VT52. CALL SEND(CHAR(27)//'G') ELSE !Reset the VT100. CALL SEND(CHAR(27)//'(B') ENDIF ENDIF RETURN END SUBROUTINE MOVE(ROW,COL) C Position cursor to ROW,COL. C Row 0 is top of screen. Row 23 is bottom-of-screen. C The leftmost column is 0. The rightmost is 79. INTEGER*2 ROW,COL IDUMMY=SCR$SET_CURSOR(%VAL(ROW+1),%VAL(COL+1)) RETURN END SUBROUTINE CLEAR C Clear screen. I=1 I=LIB$ERASE_PAGE(I,I) RETURN END SUBROUTINE DS_OBJ(CLASS) C Display object of type CLASS at current screen position. IMPLICIT INTEGER*2 (A-Z) LOGICAL FLIP,FLOP,LEFT,SLOW CHARACTER*80 BARR COMMON/CHRS/BARR(4) PARAMETER MAX_BOMBS=4 COMMON/DARTH/MAX_BOMB_ROW,SCORES,BASES,GAME 1 ,DANGER,MAX_DANGER,FLIP,FLOP,LEFT,ALIEN,B,ALIENS_LEFT 2 ,FALLING_BOMBS,SLOW 3 ,ALIEN_ROW(55),ALIEN_COL(55),BASE_ROW,BASE_COL 4 ,BASE_VEL,BEAM_ROW,BEAM_COL,BOMB_ROW(MAX_BOMBS),BOMB_COL(MAX_BOMBS) 5 ,SHIP_VAL,SHIP_COL,SHIP_VEL INTEGER CLASS IF ((GAME.EQ.4).AND.(CLASS.GE.0).AND.(CLASS.LE.5)) CLASS = 6 GO TO (1,2,3,4,5,6,7,8)CLASS+1 1 CALL SEND(' -`- ') RETURN 2 CALL SEND(' <`> ') RETURN 3 CALL SEND(' >`< ') RETURN 4 CALL SEND(' ``` ') RETURN 5 CALL SEND(' >a< ') RETURN 6 CALL SEND(' ') RETURN 7 CALL SEND(' ') RETURN 8 CALL SEND(' lwnwk ') RETURN END SUBROUTINE SEND(CHARS) C Type CHARS to screen with no or 's. CHARACTER*(*) CHARS INTEGER*2 I TYPE 1,CHARS 1 FORMAT('+',A,$) RETURN ENTRY SEND_INT(I) TYPE 2,I 2 FORMAT('+',I4,$) RETURN END