REM ***************************************************** REM * * REM * SPACE WAR * REM * For one or two Players on a Graphics Terminal * REM * Jobst Brandt * REM * Hewlett-Packard * REM * (01 Apr 82) * REM * * REM * Converted to GFA BASIC for Atari ST * REM * Eric Parent * d$="(2015-03-27)" REM ***************************************************** DIM c(46),o(21,3),q(4),s(16,2),e(8,2) DIM a$(80),d$(12),a1$(2),n$(2),n1$(16),p$(1),v1$(2) REM Star locs and size: Xmax=720, Ymax=360, Smax=0, Smin=0 DATA 0,0,0,0,10,0,-2,0,0,2,-1,0,3,2,-8,0,-2,-2,-4,0,-4 DATA -2,4,-2,4,0,2,-2,8,0,-3,2,1,0,0,2 DATA -2,6,-2,-6,-6,-2,6,-2,2,-6,2,6,6,2,-6,2 FOR i=1 TO 4 READ q(i) NEXT i FOR i=1 TO 16 FOR j=1 TO 2 READ s(i,j) NEXT j NEXT i FOR i=1 TO 8 FOR j=1 TO 2 READ e(i,j) NEXT j NEXT i @detect_screen REM - q CONTAINS Xlim,Ylim(screen),Distance,Maxsize(stars) start: n$(1)="Spock" n$(2)="Darth" m=INT(2*RND(0)+1) o=0 n1$="9" p$="2" q=@fnh(0) f1=0 f2=0 f3=0 v1$(1)="20" v1$(2)=v1$(1) prompt_players: LOCATE 1,15 PRINT "(";p$;") One or two players? : "; FORM INPUT 2,a$ ui=@fnc(a$) IF 1<=ui AND ui<=5 THEN GOTO prompt_players ENDIF IF ui=6 THEN END ENDIF IF a$="" THEN a$=p$ ENDIF q=VAL(a$) IF q<>1 AND q<>2 THEN GOTO prompt_players ENDIF p=q p$=STR$(p) IF p=1 n$(1)="Player" n$(2)="Enemy" ELSE FOR j=1 TO 2 prompt_name: LOCATE 1,15+j PRINT "(";n$(j);") Name of captian #";j;": "; FORM INPUT 20,a$ IF a$<>"" a$=TRIM$(a$) IF a$="" GOTO prompt_name ENDIF ui=@fnc(a$) n$(j)=@fns$(a$) ENDIF NEXT j ENDIF prompt_stars: LOCATE 1,18 PRINT "(";n1$;") How many stars? (0 to 18): "; FORM INPUT 2,a$ ui=@fnc(a$) IF a$="" a$=n1$ ENDIF IF NOT @isnum(a$) GOTO prompt_stars ENDIF n=INT(VAL(a$)) IF ABS(n)<0 OR ABS(n)>18 GOTO prompt_stars ENDIF n1$=STR$(n) REM O=Black hole o=ABS(n<0) n=ABS(n) q(4)=10-n/6 q(3)=53-n REM -------------------- MAKE STARS --------------------- n=n+o make_stars: i=1 WHILE i<=n r=0 makestars_nextr: r=r+1 IF r>20 i=1 ELSE o(i,3)=q(4) REM -- J: 1 = Xpos, 2 = Ypos, 3 = Mass/Size -- FOR j=3 TO 1 STEP -1 o(i,j)=INT((q(j)-2*o(i,3))*RND(0)+o(i,3)) NEXT j j=1 WHILE j<=i-1 t=(o(i,3)+o(j,3)+10)^2 IF (o(i,1)-o(j,1))^2+(o(i,2)-o(j,2))^220 GOTO make_stars ENDIF x=INT(q+i*RND(0)+t) y=INT((q(2)-30)*RND(0)+20) k=1 WHILE k<=n IF (x-o(k,1))^2+(y-o(k,2))^2<(o(k,3)*2)^2 GOTO placeships_nextr ENDIF k=k+1 WEND o(n+j,1)=x o(n+j,2)=y j=j+1 WEND a1$(1)="0" a1$(2)="180" IF p>1 a$=n$(1) n$(1)=n$(2) n$(2)=a$ ENDIF REM ------------- PLOT STARS AND SPACE SHIPS ------------ @refresh IF LEFT$(a$)="I" GOTO line1430 ENDIF GOTO line1210 REM --------------------- PLAY GAME --------------------- play_game: m=(m MOD 2)+1 line1210: IF p=1 m=1 ENDIF REM ------------------------------ Launch Angle prompt_angle: @prompt("("+a1$(m)+") "+n$(m)+"'s, launch angle: ") b=20 f1=1 FORM INPUT 15,a$ IF a$="" a$=a1$(m) ENDIF ui=@fnc(LEFT$(a$)) if ui=2 @refresh endif IF NOT @isnum(a$) GOTO prompt_angle ENDIF a=VAL(a$) a=SGN(a)*(ABS(a) MOD 360) a1$(m)=STR$(a) IF n=0 GOTO line1430 ENDIF REM ------------------------------ Initial Velocity prompt_velocity: @prompt("("+v1$(m)+") "+n$(m)+"'s initial velocity (0 to 20): ") FORM INPUT 15,a$ IF a$="" a$=v1$(m) ENDIF ui=@fnc(LEFT$(a$)) if ui=1 goto prompt_angle endif if ui=2 @refresh endif IF NOT @isnum(a$) GOTO prompt_velocity ENDIF b=VAL(a$) IF b<0 OR b>20 GOTO prompt_velocity ENDIF v1$(m)=STR$(b) line1430: u1=0 u2=0 v1=0 v2=0 f3=0 x=0.35*b*COS(a*z1) y=0.35*b*SIN(a*z1) u=x+o(n+m,1)+8*COS(a*z1) v=y+o(n+m,2)+8*SIN(a*z1) @fng(u,v) line1510: IF f2 GOTO line1570 ENDIF REM ----------------- DRAW ROCKET PATH ------------------ u1=INT(u+0.5) v1=INT(v+0.5) IF u1<>u2 OR v1<>v2 @drawline2(u1,v1) ENDIF u2=u1 v2=v1 REM -- E = Xforce, F = Yforce -- line1570: e=0 f=0 FOR j=1 TO n r5=o(j,1)-u r6=o(j,2)-v r4=r5^2+r6^2 r3=SQR(r4) r2=r5/r3 r1=r6/r3 g=0.017*(o(j,3)^3)/r4 e=e+g*r2 f=f+g*r1 NEXT j x=x+e y=y+f u=u+x v=v+y REM ------------------ FIND COLLISIONS ------------------ IF NOT f2 j=1 WHILE j<=n+2 IF (NOT o) OR j<>n IF (u-o(j,1))^2+(v-o(j,2))^2q(1)*2 OR v<-q(2) OR v>q(2)*2 GOTO play_game ENDIF f2=(u<0 OR u>q(1) OR v<0 OR v>q(2)) REM -- F2=F3 (no change............) -- REM -- F2=1 (just went off screen.) -- REM -- F3=1 (just came onto screen) -- IF f2=f3 GOTO line1510 ENDIF IF f3 @fng(u,v) ENDIF f3=f2 GOTO line1510 REM ------------------ MAKE EXPLOSIONS ------------------ make_explosions: @fng(u+2,v+2) FOR i=1 TO 8 @drawline(e(i,1),e(i,2)) NEXT i IF j<=n GOTO play_game ENDIF REM ------------------------------ Play again? prompt_playagain: @prompt(n$(m)+" destroyed "+n$(j-n)+"'s ship! (Y) Again? : ") FORM INPUT 2,a$ a$=UPPER$(LEFT$(a$)) IF a$="" OR a$="Y" goto start ENDIF IF a$<>"N" GOTO prompt_playagain ENDIF END REM ------------------------------------------------------------ REM user input REM ------------------------------------------------------------ FUNCTION fnc(i$) LOCAL p IF @isnum(a$) THEN RETURN 0 ENDIF i$=UPPER$(i$) IF i$="!" @dump_vars @refresh ENDIF p=INSTR("BDHS/E",i$) IF LEFT$(a$,2)="//" p=6 ELSE IF p=3 q=@fnh(0) ENDIF RETURN p ENDFUNC PROCEDURE prompt(p$) LOCATE 1,24 PRINT SPACE$(75); LOCATE 1,24 PRINT p$; RETURN FUNCTION isnum(s$) LOCAL z IF LEN(s$) THEN z=ASC(a$) IF (48<=z AND z<=57) OR z=45 OR z=46 THEN RETURN TRUE ENDIF ENDIF RETURN FALSE ENDFUNC REM ------------------------------------------------------------ REM Draw Ship REM ------------------------------------------------------------ PROCEDURE draw_ship(x,y,a$,p) s=(p-1)*2-1 @fng(x,y) FOR k=1 TO 16 @drawline(s(k,1)*s,s(k,2)) NEXT k RETURN PROCEDURE draw_ships FOR i=1 TO 2 @draw_ship(o(n+i,1),o(n+i,2),n$(i),i) NEXT i RETURN REM ------------------------------------------------------------ REM Set X,Y for next draw REM ------------------------------------------------------------ PROCEDURE fng(x,y) cx=x cy=y RETURN REM ------------------------------------------------------------ REM Check and draw line if visible REM ------------------------------------------------------------ PROCEDURE drawline(x,y) IF cx>=0 AND cx<=q(1) AND cy>=0 AND cy<=q(2) AND cx+x>=0 AND cx+x<=q(1) AND cy+y>=0 AND cy+y<=q(2) LINE cx,cy,cx+x,cy+y ENDIF cx=cx+x cy=cy+y RETURN PROCEDURE drawline2(x,y) IF cx>=0 AND cx<=q(1) AND cy>=0 AND cy<=q(2) AND x>=0 AND x<=q(1) AND y>=0 AND y<=q(2) LINE cx,cy,x,y ENDIF cx=x cy=y RETURN REM ------------------------------------------------------------ REM Display Help REM ------------------------------------------------------------ FUNCTION fnh(z) a$=SPACE$(4) CLS PRINT "SPACE WAR ";d$ PRINT PRINT a$;" Commands:" PRINT PRINT a$;" H = Help" PRINT a$;" S = Start" PRINT a$;" D = Display" PRINT a$;" I = Instant replay after hit" PRINT a$;" / or B = Back" PRINT a$;"// or E = Exit" PRINT PRINT "Negative number of stars gives a BLACK HOLE" PRINT readytoplay_prompt: LOCATE 1,14 PRINT "(Y) Are you ready to play? (Y/N): "; FORM INPUT 2,a$ a$=UPPER$(a$) IF LEFT$(a$)="N" OR LEFT$(a$)="E" OR a$="//" THEN END ENDIF IF a$="H" THEN GOTO readytoplay_prompt ENDIF RETURN 0 ENDFUNC REM ************** FUNCTION DOWNSHIFT *********** FNS$ ** FUNCTION fns$(z$) z$=UPPER$(z$) FOR i=2 TO LEN(z$) k=ASC(MID$(z$,i,1)) IF 65<=k AND k<=91 THEN MID$(z$,i,1)=CHR$(k+32) ENDIF NEXT i RETURN z$ ENDFUNC REM ------------------------------------------------------------ REM detect screen capability REM ------------------------------------------------------------ PROCEDURE detect_screen r%=XBIOS(4) if r%=0 ! low res q(1)=319 else q(1)=639 endif if r%=2 ! high res q(2)=399-32 else q(2)=199-16 endif RETURN REM ------------------------------------------------------------ REM refresh game display REM ------------------------------------------------------------ PROCEDURE refresh CLS @draw_stars @draw_ships RETURN REM ------------------------------------------------------------ REM draw all the stars REM ------------------------------------------------------------ PROCEDURE draw_stars z1=PI*(1/180) FOR i=0 TO 45 c(i+1)=COS(i*10*z1) NEXT i FOR i=1 TO n-o FOR j=1 TO 37 x=INT(o(i,1)+o(i,3)*c(j)+0.5) y=INT(o(i,2)-o(i,3)*c(j+9)+0.5) IF j=1 PLOT x,y ELSE DRAW TO x,y ENDIF NEXT j NEXT i RETURN REM ------------------------------------------------------------ REM dump variables REM ------------------------------------------------------------ PROCEDURE dump_vars CLS FOR i=1 TO 4 LOCATE 1,i PRINT "q(";i;")=";q(i) NEXT i LOCATE 25,1 FOR i=1 TO n LOCATE 25,i PRINT "o(";i;",)=";o(i,1);",";o(i,2);",";o(i,3); NEXT i j=n+1 FOR i=j TO j+1 LOCATE 25,i+1 PRINT "o(";i;",)=";o(i,1);",";o(i,2);",";o(i,3); NEXT i LOCATE 1,24 PRINT "Press Enter/Return: "; FORM INPUT 1,a$ RETURN