Home > Space War for Atari ST
Release 1Mar 27, 2015Download 5K Zip
AboutScreenshotSource

Space War is a game written by Jobst Brandt at Hewlett-Packard in April 1982. I ported his BASIC code to GFA Basic for the Atari ST. This was done in response to a BASIC Challenge by Retro Battlestations on Reddit. The Atari ST version will play in all three of the ST screen resolutions.

The Download Zip contains SPACEWAR.GFA and SPACEWAR.TXT

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