' Cannon Warfare
'
' Graphics by Robert Coletti
' Programming by Patrick Farley and Robert Coletti
'
' Written in compiled GFA Baisc.
Gosub Main_loop
Procedure Main_loop
  Res=Xbios(4)+1
  If Res=2 Or Res=3
    Alert 0,"  Run in Lo Resolution only.  |",0,"Okay",B
    End
  Endif
  If Noload=0 Then                         !Check if Graphics is loaded
    Gosub Space                            !If not, load them into
    Gosub Load                             !memory.
  Endif
  Gosub Sprite                             !Create Sprites
  Gosub Title                              !Gosub the Title Procedure
  Fl=0                                     !Set the RGB values of all
  Gosub Flash                              !16 colors to 0.
  Gosub Define                             !Setup positions of various things.
  Gosub Back                               !draw the backround and ocean.
  Gosub Print_stuff                        !Prints the top values as empty.
  Gosub Island                             !draws the islands.
  Gosub Mountain                           !Draws the Mountain.
  Restore Cols1                            !This tells SETCOLOR to use
  Gosub Setcolor                           !COLS1 as the set of colors
  Gosub Go_t                               !Sets game up to start.
Return
Procedure Define
  Cls
  Pn=3.141593/180                          !sets ã as ã/180
  Iv=0
  Wind=Int(Rnd(1)*10)                      !sets the Wind
  If Rnd(1)>0.5 Then                       !and the direction it is in.
    Wind=-Wind
  Endif
  Color 1
  Np=0
  P=Rnd(1)*20+139
  Hg=Rnd(0)*50+25
  For I=1 To 100
    Sq(I)=(I/10)*(I/10)
  Next I
Return
Procedure Back
  For I=1 To 319                           !This procedure PUTs
    Yy(I)=P                                !the ocean and backround.
  Next I
  For J=160 To P Step -1
    Draw 0,J To 319,J
  Next J
  Deffill 6,2,8
  Pbox 0,50,319,199
  Put 0,45,Backgrnd$
  Deffill 14,2,8
  Pbox 0,160,319,199
  Put 0,P-10,Soup1$
Return
Procedure Go_t
  Hidem                                    !This procedure hides the mouse
  Repeat                                   !pointer and produces the game loop.
    Gosub Turn
  Until Mousek=1
  Gosub Fot
Return
Procedure Load
  Bload "OCEAN.PUT",Varptr(Soup1$)         !into memory.
  Bload "ISLAND1.PUT",Varptr(Island1$)
  Bload "ISLAND2.PUT",Varptr(Island2$)
  Bload "BACKGRND.PUT",Varptr(Backgrnd$)
  Bload "CANBALL.PUT",Varptr(Ball$)
  Bload "TITLE.PUT",Varptr(Title$)
  Bload "HELP.PUT",Varptr(Help$)
  Bload "TITLESC2.PUT",Varptr(Hard$)
  Bload "EXPLOSI1.PUT",Varptr(Ex1$)
  Bload "EXPLOSI2.PUT",Varptr(Ex2$)
  Bload "EXPLOSI3.PUT",Varptr(Ex3$)
  Bload "EXPLOSI4.PUT",Varptr(Ex4$)
  Bload "EXPLOSI5.PUT",Varptr(Ex5$)
  Bload "EXPLOSI6.PUT",Varptr(Ex6$)
  Bload "EXPLOSI7.PUT",Varptr(Ex7$)
  Bload "EXPLOS21.PUT",Varptr(Ex21$)
  Bload "EXPLOS22.PUT",Varptr(Ex22$)
  Bload "EXPLOS23.PUT",Varptr(Ex23$)
  Bload "EXPLOS24.PUT",Varptr(Ex24$)
  Bload "EXPLOS25.PUT",Varptr(Ex25$)
  Bload "EXPLOS26.PUT",Varptr(Ex26$)
  Bload "EXPLOS27.PUT",Varptr(Ex27$)
Return
Procedure Space
  Dim Yy(320),Sq(100),Ax(100),Ay(100),B(4),Line1$(7),R$(1)
  Hard$=Space$(1606)
  Title$=Space$(32006)
  Hard$=Space$(32006)
  Help$=Space$(32006)                      !This procedure leaves space for
  Backgrnd$=Space$(15046)                  !variables and graphics.
  Soup1$=Space$(5926)
  Island1$=Space$(500)
  Island2$=Space$(500)
  Ball$=Space$(38)
  Ex1$=Space$(1062)
  Ex2$=Space$(1062)
  Ex3$=Space$(1062)
  Ex4$=Space$(1062)
  Ex5$=Space$(1062)
  Ex6$=Space$(1062)
  Ex7$=Space$(1062)
  Ex21$=Space$(1062)
  Ex22$=Space$(1062)
  Ex23$=Space$(1062)
  Ex24$=Space$(1062)
  Ex25$=Space$(1062)
  Ex26$=Space$(1062)
  Ex27$=Space$(1062)
Return
Procedure Title
  Key$=Inkey$                              !This procedure displays the
  Hidem                                    !Title screen and waits until
  Fl=0                                     !a key is pressed.
  Gosub Flash
  Put 0,0,Title$
  Restore Cols2
  Gosub Setcolor
  Gg=1
  Do
    Key$=Inkey$
    Pause 3
    If Key$="Q" Or Key$="q" Then
      System
    Endif
    If Key$="H" Or Key$="h" Then
      Gosub Help
    Endif
    If Key$="L" Or Key$="l" And Gg=1 Then
      Put 0,0,Hard$
      Gg=2
      Skip=1
    Endif
    If Skip=0 And Key$="L" Or Skip=0 And Key$="l" And Gg=2 Then
      Gosub Easy
    Endif
    Skip=0
    Exit If Key$="P" Or Key$="p"
  Loop
  Cls
Return
Procedure Setcolor
  For I=0 To 15                            !This procedure sets the colors
    Read C,R,G,B                           !to one of the two RESTOREd palettes
    Setcolor C,R,G,B
  Next I
  Cols1:
  Data 0,0,0,0
  Data 1,7,0,0
  Data 2,0,0,2
  Data 3,0,0,3
  Data 4,7,5,3
  Data 5,5,3,1
  Data 6,0,5,0
  Data 7,0,7,0
  Data 8,4,3,1
  Data 9,6,5,3
  Data 10,7,6,4
  Data 11,3,4,7
  Data 12,5,6,7
  Data 13,3,3,3
  Data 14,5,5,5
  Data 15,7,7,7
  Cols2:
  Data 0,0,0,0
  Data 1,7,0,0
  Data 2,0,0,2
  Data 3,0,0,3
  Data 4,1,1,1
  Data 5,2,2,2
  Data 6,0,5,0
  Data 7,7,0,0
  Data 8,4,3,1
  Data 9,4,4,4
  Data 10,6,6,6
  Data 11,7,5,0
  Data 12,7,6,3
  Data 13,3,3,3
  Data 14,5,5,5
  Data 15,7,7,7
Return
Procedure Restore_colors
  Setcolor 0,7,7,7                         !Restore the Desktop colors
  Setcolor 1,0,0,0                         !before quitting.
  Setcolor 2,0,0,0
  Setcolor 3,0,0,0
  Setcolor 4,0,0,0
Return
Procedure Fot
  Gosub Restore_colors                     !Restore colors and end program.
  End
Return
Procedure Mountain
  For I=141 To 179                         !Draw the Mountain
    Yy(I)=Sin(((I-140)*4.5+180)*Pn)*Hg+P-4
    Color 9
    Draw I+3,Yy(I) To I+3,P-4
  Next I
Return
Procedure Island
  B(1)=Rnd(1)*20+60-5*Abs(Wind)            !Draw the Island.
  B(2)=Rnd(1)*20+240+5*Abs(Wind)
  Put B(1)-20,P-9,Island1$
  Put B(2)-8,P-9,Island2$
Return
Procedure Get_angle
  Get 0,16,319,199,Screen$                 !INPUTs the angle
  Angle=0
  Repeat
    Print At(Turn,3);
    Input "Angle: ",Angle$
    Angle=Val(Angle$)
    If Angle<5 Or Angle>175 Then
      Gosub Bad_value
      Angle=0
    Else
      Print At(Turn-1,1);"Angle: ";Angle;"  "
      Put 0,16,Screen$
    Endif
  Until Angle>0
Return
Procedure Get_bags
  Get 0,16,319,199,Screen$               !INPUTs the amount of bags
  Bags=0
  Repeat
    Print At(Turn,3);
    Input "Bags: ",Bags$
    Bags=Val(Bags$)
    If Bags<>Int(Bags) Or Bags<1 Or Bags>40 Then
      Gosub Bad_value
      Bags=0
    Else
      Print At(Turn-1,2);"Bags:  ";Bags;"  "
      Put 0,16,Screen$
    Endif
  Until Bags>0
Return
Procedure Bad_value
  Put 0,16,Screen$                       !Shows the Bad value prompt
  Print At(15,5);"BAD VALUE!"
  Pause 50
  Put 0,16,Screen$
Return
Procedure Turn
  Turn=2                                 !Goes through one full turn
  Np=0
  Gosub Get_angle
  Gosub Get_bags
  Gosub Launch
  Turn=29
  Np=1
  Gosub Get_angle
  Gosub Get_bags
  Gosub Launch
Return
Procedure Launch
  Get 0,0,319,199,Screen2$                !Launches the cannonball
  Bags=Bags*10
  If Np=1 Then
    Angle=Angle+180
  Endif
  If Np=1 Then
    Ntnp=0
  Endif
  If Np=0 Then
    Ntnp=1
  Endif
  Py=P-5
  Px=B(Np+1)
  Iv=0
  Do
    Iv=Iv+1                                               !Cannonball path's
    Ballx=Iv*Bags*Cos(Angle*Pn)/10+B(Np+1)-Wind*Sq(Iv)    !math.
    Bally=Iv*Bags*Sin(Angle*Pn)/10
    Bally=P+((Ntnp)*-1+Np)*Bally+16*Sq(Iv)
    Exit If Ballx>316 Or Ballx<3 Or Bally<-1000
    If Bally>P+7 Then
      D=5
    Endif
    If D=0 And Ballx>B(Np+1)-5 And Ballx<B(Np+1)+5 Then
      Net=1
    Endif
    If Net=0 Then
      Ym=(Abs(Py-Bally)/((Abs(Px-Ballx))+0.0001))*Sgn(Bally-Py)
      St=Sgn(Ballx-Px)
      Rn=(Ballx-Px)
      Cc=0
      If N=1 Then
        Cc=Rn
        Rn=0
        St=-St
      Endif
      Repeat
        L=Px+Cc
        M=Py+Ym*Abs(Cc)
        If Yy(L)<M Then
          Gosub Next2
        Endif
        If Bally>P Then
          Gosub Next2
        Endif
        Exit If Verto=1
        Verto=0
        Cc=Cc+St
      Until Abs(Cc-Rn)<=Abs(St)
    Endif
    D=0
    Net=0
    Vsync
    Put 0,0,Screen2$
    Put Ballx,Bally+4,Ball$                        !draw cannonball
    Sprite Cball1$,Ballx-3,P-5
    Px=Ballx
    Py=Bally
    If Yy(Ballx)<Bally Then
      L=Ballx
      M=Yy(Ballx)
      Drf=1
    Endif
    Exit If Drf=1
  Loop
  Drf=0
  Gosub Splash
  Vsync
  Put 0,0,Screen2$
  Defline 1,1,0,0
  Color 2
  If Gg=1                                        !If level is easy, then
    Draw Ballx,Bally-1 To Ballx+1,Bally-1        !draw red dot where cannonball
    Draw Ballx-1,Bally To Ballx+2,Bally          !hit.
    Draw Ballx,Bally+1 To Ballx+1,Bally+1
    Color 0
    Draw Ballx,Bally
  Endif
Return
Procedure Next2
  X1=Abs(Ballx-B(1))
  X2=Abs(Ballx-B(2))
  If Gg=1
    If X1<20 Or X2<20 Then
      Gosub Destruction
    Endif
  Endif
  If Gg=2
    If X1<4 Or X2<4
      Gosub Destruction
    Endif
  Endif
  If Ballx<3 Or Ballx>316 Then
    Verto=1
  Endif
Return
Procedure Splash
  Wave 8,1,3,15000,0
Return
Procedure Print_stuff
  Print At(1,1);"Angle: 0"                !Prints the top status line with data
  Print At(1,2);"Bags:  0"
  Print At(28,1);"Angle: 0"
  Print At(28,2);"Bags:  0"
  Print At(15,1);"Wind: ";Abs(Wind)
  If Wind>0 Then                          !Prints wind
    Print At(18,2);"<--"
  Endif
  If Wind<0 Then
    Print At(18,2);"-->"
  Endif
Return
Procedure Setcolor2
  Setcolor 0,0,0,0                        !Sets explosion colors
  Setcolor 1,7,0,0
  Setcolor 2,1,0,1
  Setcolor 3,2,1,2
  Setcolor 4,7,5,3
  Setcolor 5,5,3,1
  Setcolor 6,0,5,0
  Setcolor 7,0,7,0
  Setcolor 8,4,3,1
  Setcolor 9,6,5,3
  Setcolor 10,7,6,4
  Setcolor 11,5,4,7
  Setcolor 12,6,6,7
  Setcolor 13,3,2,2
  Setcolor 14,6,5,5
  Setcolor 15,7,6,6
Return
Procedure Setcolor3
  Setcolor 1,7,0,0                       !second explosion colors
  Setcolor 2,2,0,0
  Setcolor 3,3,0,0
  Setcolor 4,7,3,0
  Setcolor 5,7,5,0
  Setcolor 11,6,4,5
  Setcolor 12,7,6,7
  Setcolor 13,3,1,1
  Setcolor 14,5,3,3
  Setcolor 15,7,5,5
Return
Procedure Destruction
  Fl=7                                 !Turns screen
  Gosub Flash                          !white
  Pause 3                              !for 3 PAUSE units
  Gosub Setcolor2                      !and then
  Pause 2                              !slowly
  Gosub Setcolor3                      !changes the backround
  If Np=0 Then                         !colors to pinkish.
    Gosub Erty
  Endif                                 !Then it sees which cannon should
  If Np=1 Then
    Gosub Gity                         !explode!
  Endif
  Noload=1                             !Never will load graphics again
  Gosub Main_loop                      !until game is rebooted
Return
Procedure Chip
  Put B(1)-26,P-13,Ex1$                !left cannon destruct.
  Gosub Sync
  Put B(1)-26,P-12,Ex2$                !NOTE: difference in coordinates is
  Gosub Sync                           !due to errors in PUTing graphics.
  Put B(1)-26,P-12,Ex3$
  Gosub Sync
  Put B(1)-23,P-14,Ex4$
  Gosub Sync
  Put B(1)-23,P-13,Ex5$
  Gosub Sync
  Put B(1)-23,P-13,Ex6$
  Gosub Sync
  Put B(1)-25,P-13,Ex7$
  Gosub Sync
  Pause 50
Return
Procedure Rip
  Put B(2)-19,P-13,Ex21$              !Right cannon destruct.
  Gosub Sync
  Put B(2)-19,P-12,Ex22$
  Gosub Sync
  Put B(2)-19,P-12,Ex23$
  Gosub Sync
  Put B(2)-20,P-14,Ex24$
  Gosub Sync
  Put B(2)-20,P-13,Ex25$
  Gosub Sync
  Put B(2)-21,P-13,Ex26$
  Gosub Sync
  Put B(2)-19,P-13,Ex27$
  Gosub Sync
  Pause 50
Return
Procedure Sync
  For I=1 To 10                     !Wait for screen to syncronise
    Vsync                           !and make explosion sound
    Wave 10,1,3,15000,0             !10 times.
  Next I
Return
Procedure Flash
  For I=0 To 15                     !Changes all 16 colors' RGB values
    Setcolor I,Fl,Fl,Fl             !to the brightness Value of FL (0-7).
  Next I
  Pause 2
Return
Procedure Help
  Fl=0                              !PUTs the help screen and then
  Gosub Flash                       !waits until keypress.
  Put 0,0,Help$
  Restore Cols1
  Gosub Setcolor
  Repeat
    Key$=Inkey$
  Until Key$<>""
  Gosub Flash
  Gosub Title
Return
Procedure Sprite
  Let Cball1$=Mki$(0)+Mki$(0)      !Creates the sprite in string CBALL1$
  Let Cball1$=Cball1$+Mki$(0)
  Let Cball1$=Cball1$+Mki$(0)
  Let Cball1$=Cball1$+Mki$(3)
  Restore Spr
  For I%=1 To 16
    Read Foregrnd,Backgrnd
    Let Cball1$=Cball1$+Mki$(Backgrnd)+Mki$(Foregrnd)
  Next I%
  Spr:
  Data 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  Data 0,0,0,0,0,0,384,0,2016,0,384,0,0,0,0,0
Return
Procedure Easy
  Put 0,0,Title$
  Gg=1
Return
Procedure Gity
  If Gg=2 And Abs(Ballx-B(1))<4 Or Gg=1 And Abs(Ballx-B(1))<30
    Gosub Chip
  Endif
  If Gg=2 And Abs(Ballx-B(2))<4 Or Gg=1 And Abs(Ballx-B(2))<30
    Gosub Rip
  Endif
  Noload=1
  Gosub Main_loop
Return
Procedure Erty
  If Gg=2 And Abs(Ballx-B(2))<4 Or Gg=1 And Abs(Ballx-B(2))<30
    Gosub Rip
  Endif
  If Gg=2 And Abs(Ballx-B(1))<4 Or Gg=1 And Abs(Ballx-B(1))<30
    Gosub Chip
  Endif
Return
