DECLARE SUB DrawHUD ()
DEFINT A-Z
'$DYNAMIC

DECLARE SUB SetCam (X%, Y%, Zoom AS SINGLE)
DECLARE SUB DoLighting ()
DECLARE SUB AddLight (X AS INTEGER, Y AS INTEGER, Size AS INTEGER, Colour AS INTEGER)
DECLARE SUB BBoxF (X1%, Y1%, X2%, Y2%, C%)
DECLARE SUB Delay (Time AS DOUBLE)
DECLARE SUB DoHighScores (KillEff#, WhatToDo%)
DECLARE SUB DoStars ()
DECLARE SUB FireWeapon (WeaponSelect AS INTEGER)
DECLARE SUB GetInput (Index%, Up%, Left%, Down%, Right%, Brake%, Shoot%, Quit%)
DECLARE SUB HandleCBExp (cbm AS INTEGER, X%, Y%)
DECLARE SUB HandleRML5K ()
DECLARE SUB LOAD.InitVideo ()
DECLARE SUB MakeWeaponSound (WeaponSelect%)
DECLARE SUB O2D.Check (Object AS ANY)
DECLARE SUB O2D.Draw (Object AS ANY)
DECLARE SUB O2D.GetRadius (Object AS ANY)
DECLARE SUB O2D.MTScreen (Object AS ANY)
DECLARE SUB O2D.MTScreenAK (Object AS ANY)
DECLARE SUB O2D.Propell (Object AS ANY, Speed AS SINGLE)
DECLARE SUB PRJ.AddProjectile (Projs() AS ANY, fObject AS ANY, Template AS ANY, MAXPROJS AS INTEGER)
DECLARE SUB PRJ.CheckCollide (Projs() AS ANY, Object AS ANY, MAXPROJS AS INTEGER, rx%, ry%, rj%)
DECLARE SUB PRJ.ClearProjectiles (Projs() AS ANY, MAXPROJS AS INTEGER)
DECLARE SUB PRJ.MoveAndDrawProjectiles (Projs() AS ANY, MAXPROJS AS INTEGER)
DECLARE SUB PRT.AddPart (X%, Y%, Xd AS SINGLE, Yd AS SINGLE, Size AS INTEGER, Ttl AS INTEGER, SetClr AS INTEGER, Colour AS INTEGER, Flags AS INTEGER)
DECLARE SUB PRT.CircleExp (X%, Y%, density%, Size%, grav%)
DECLARE SUB PRT.ClearAllParts ()
DECLARE SUB PRT.ImplodeText (Text$, ex%, ey%, Size%)
DECLARE SUB PRT.MoveAndDrawParticles ()
DECLARE SUB SetNumlocks ()
DECLARE SUB TX.CLS ()
DECLARE SUB TX.CPrint (Text$)
DECLARE SUB TX.Locate (Y%)
DECLARE SUB TX.Print (Text$)
DECLARE FUNCTION BlahS$ (N%)
DECLARE FUNCTION Distance% (X%, Y%, X1%, Y1%)
DECLARE SUB ENMY.AddEnemy (EnemyN AS INTEGER, X%, Y%, Ang%)
DECLARE SUB ENMY.DoAi (I%)
DECLARE SUB ENMY.DoTrail (I%, OldX%, OldY%)
DECLARE SUB ENMY.DrawEnemys (I%)
DECLARE SUB ENMY.Track (I%, X%, Y%)
DECLARE SUB LoadLMLevel (FileName AS STRING)
DECLARE FUNCTION PlayLevel% (Wave%, Level%, NetScore%)
DECLARE SUB PWRUP.AddPowerUp (Index%, X%, Y%)
DECLARE SUB PWRUP.ClearPowerUps ()
DECLARE SUB PWRUP.MoveAndDraw (I%)
DECLARE SUB SpawnEnemy (Obj AS ANY)
DECLARE SUB Explosions (st#)
DECLARE SUB LMMid ()
DECLARE SUB PlaySound (SoundN%)
DECLARE SUB ScrollMessage (FileName AS STRING)
DECLARE SUB LMStart ()
DECLARE SUB DEB.Clear ()
DECLARE SUB DEB.Add (X%, Y%, Angle%, Speed%, Scale%)
DECLARE SUB DEB.MoveDraw ()

DECLARE SUB BBoxF64 (BYVAL Layer AS INTEGER, BYVAL X1 AS INTEGER, BYVAL Y1 AS INTEGER, BYVAL X2 AS INTEGER, BYVAL Y2 AS INTEGER, BYVAL Colour AS INTEGER)

'$INCLUDE: 'DEXTERN.BI'
'$INCLUDE: 'XGMAE.BI'

REM $STATIC
SUB ENMY.AddEnemy (EnemyN AS INTEGER, X, Y, Ang)
 FOR I = 1 TO MAXENEMYS
  IF Enemys(I).Used = 0 THEN
   Enemys(I) = EnemyTemplate(EnemyN)
   Enemys(I).Object.X = X
   Enemys(I).Object.Y = Y
   Enemys(I).Object.Ang = Ang
   Enemys(I).Status = 1
   Enemys(I).Used = -1
   EXIT SUB
  END IF
 NEXT I
END SUB

SUB ENMY.DoTrail (I, OldX, OldY)
 IF Enemys(I).Trail THEN
  A = ((Enemys(I).Object.Ang + 180 + 720) MOD 360)
  NewX = Enemys(I).Object.X + (Enemys(I).Object.X - OldX) + ((Enemys(I).Object.Radius * Enemys(I).Object.Scale) * Cosine(A))
  NewY = Enemys(I).Object.Y + (Enemys(I).Object.Y - OldY) + ((Enemys(I).Object.Radius * Enemys(I).Object.Scale) * Sine(A))
  R = RND
  R = R - (R / 2)
  PRT.AddPart INT(NewX), INT(NewY), -((Enemys(I).Object.X - OldX) / 10) + R, -((Enemys(I).Object.Y - OldY) / 10) + R, 3, 20, 0, Enemys(I).Trail, 0
  AddLight INT(NewX), INT(NewY), 20, Enemys(I).Object.Colour
 END IF
END SUB

SUB ENMY.DrawEnemys (I)
 IF Enemys(I).Used THEN
  O2D.Check Enemys(I).Object
  O2D.Draw Enemys(I).Object
 END IF
END SUB

SUB ENMY.Track (I, X, Y)
 Angle2 = FindAngle(INT(Enemys(I).Object.X), INT(Enemys(I).Object.Y), X, Y)
 Angle2 = ((Angle2 + 720) MOD 360)
 Angle1 = Enemys(I).Object.Ang
 Diff1 = Angle1 - Angle2
 Diff2 = 360 + Angle1 - Angle2
 IF ABS(Diff1) > ABS(Diff2) THEN Diff1 = Diff2
 Inc = -(Diff1 / 20)
 IF ABS(Diff1) <= 10 THEN Enemys(I).Object.Ang = Angle2: EXIT SUB
 IF ABS(Inc) > 10 THEN Inc = 10 * SGN(Inc)
 IF Enemys(I).TurnSpeed THEN Inc = Inc * (Enemys(I).TurnSpeed / 10)
 Enemys(I).Object.Ang = Enemys(I).Object.Ang + Inc
END SUB

SUB GAME.LevelMode

 DiffLev = 0

 FOR I = 1 TO 8
  HaveWeapon(I) = 0
 NEXT I

 Sel = 1
 SelI = 8

 st# = TIMER

 CSSetTimer 0, 25

 DO
  CSWaitTimer 0
  CSClear EMS.Layer, 0

  DoStars
  PRT.MoveAndDrawParticles
  BBoxF64 EMS.Layer, 80, 92, 238, 132, 143

  Explosions st#

  TX.Locate 11

   TX.CPrint "ž Difficulty ž"
   TX.CPrint "ŚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄæ"
  FOR d = 1 TO 4
   TX.CPrint "³                   ³"
  NEXT
   TX.CPrint "ĄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄŁ"

  TX.Locate 13

  Text.Colour = 255: TX.CPrint " I'm a cry baby  "
                     TX.CPrint " Guns scare me   "
                     TX.CPrint " I kill for fun  "
                     TX.CPrint " Back            "

  Sela = SelI + (11 * 8)
  BBoxF64 EMS.Layer, 92, Sela, 92 + 136, Sela + 7, 143

  k$ = ""
  FOR I = 1 TO 16
   G$ = UCASE$(INKEY$)
   IF G$ <> "" AND TIMER - pauseK# > .1 THEN k$ = G$: pauseK# = TIMER
  NEXT I

  IF Sel * 8 > SelI THEN SelI = SelI + (MenuStep + (3 * -((Sel + 1 <> OSel) AND (Sel - 1 <> OSel))))
  IF Sel * 8 < SelI THEN SelI = SelI - (MenuStep + (3 * -((Sel + 1 <> OSel) AND (Sel - 1 <> OSel))))
  
  SELECT CASE k$
   CASE CHR$(0) + "P"
    IF Sel * 8 = SelI THEN OSel = Sel: Sel = Sel + 1
    IF Sel > 4 THEN Sel = 1
    DS4QB.PlaySoundEx 7, 44050, CURRENT, CURRENT, CURRENT
   CASE CHR$(0) + "H"
    IF Sel * 8 = SelI THEN OSel = Sel: Sel = Sel - 1
    IF Sel < 1 THEN Sel = 4
    DS4QB.PlaySoundEx 7, 44050, CURRENT, CURRENT, CURRENT
   CASE CHR$(13), CHR$(32):
    SELECT CASE Sel
     CASE 1
      DS4QB.PlaySoundEx 4, 22050, CURRENT, CURRENT, CURRENT
      DiffLev = 1
     CASE 2
      DS4QB.PlaySoundEx 4, 22050, CURRENT, CURRENT, CURRENT
      DiffLev = 2
     CASE 3
      DS4QB.PlaySoundEx 4, 22050, CURRENT, CURRENT, CURRENT
      DiffLev = 3
     CASE 4
      DS4QB.PlaySoundEx 4, 22050, CURRENT, CURRENT, CURRENT
      EXIT SUB
     CASE ELSE
      DS4QB.PlaySoundEx 3, 44050, CURRENT, CURRENT, CURRENT
     END SELECT
   CASE CHR$(27): Sel = 4
  END SELECT

  CSPcopy EMS.Layer, &HA000
 LOOP UNTIL DiffLev

 SELECT CASE DiffLev
  CASE 1
   Lives = 7
   HaveWeapon(1) = -1
   HaveWeapon(2) = 5
   ScoreLose = 30
  CASE 2, 3
   Lives = 5
   HaveWeapon(1) = -1
   ScoreLose = 15
 END SELECT

 FOR J = 1 TO 1
  IF J = 1 THEN LMStart
  'IF j = 2 THEN LMMid

  FOR I = 1 TO 9
   IF Lives THEN R = PlayLevel(J, I, TScore) ELSE GOTO blaherASDF
   SELECT CASE R
    CASE 1
    CASE -1: I = I - 1: IF DiffLev > 1 THEN Lives = Lives - 1
    CASE -2: GOTO blaherASDF
    CASE -4: I = I - 1
   END SELECT
  NEXT
 NEXT

 CSClear &HA000, 0

 Delay 2

 ScrollMessage "XGTXT03.TXT"

blaherASDF:
 CSSetTimer 0, 25

END SUB

SUB GAME.MultyPlayer
 DIM Score(1 TO 2) AS INTEGER
 DIM MyShips(1 TO 2) AS Object2D
 DIM keyon(1 TO 2) AS INTEGER
 DIM OldX(1 TO 2), OldY(1 TO 2)

 PRT.ClearAllParts

 Control(1) = CONTRL.HERE
 Control(2) = CONTRL.HERE

 TX.CLS

 mul = 1

 MConnectionEstablished = 0

 ' Connection Routine:
 SELECT CASE MIPX.TCP.MODEM
  CASE MPLAY.IPX     ' IPX/SPX Connection Routine
   Socket(1) = &H64F4
   Socket(2) = &H64F5
   Send = Socket(1)
   Listen = Socket(2)

   FOR Socket = Socket(1) TO Socket(2)
    CALL OpenSocket(Socket, Status%, SocketNumberReturned%)
    IF Status = &HFE THEN
       TX.Print "No Send socket available."
       GOSUB GMErrorExit
    END IF
    IF Status <> 0 THEN
       TX.Print "Error opening Socket" + STR$(Socket)
       GOSUB GMErrorExit
    END IF
    TX.Print "Opened Socket" + STR$(Socket)
   NEXT Socket

   IPXS.Checksum = 0
   IPXS.Length = LEN(IPXS)
   IPXS.Control = CHR$(0)
   IPXS.PacketType = CHR$(0)
   IPXS.DestNet = STRING$(4, &H0)
   IPXS.DestNode = STRING$(6, &HFF)
   IPXS.DestSocket = MKI$(Socket(1))
   IPXS.SourSock = MKI$(&H740)
   IPXS.Datagram = CHR$(26)
  
   ECBS.ESRAddressOff = 0
   ECBS.ESRAddressSeg = 0
   ECBS.SockNum = Socket(1)
   ECBS.ImmAdd = STRING$(6, &HFF)
   ECBS.FragCount = 1
   ECBS.FragAddOfs = VARPTR(IPXS)
   ECBS.FragAddSeg = VARSEG(IPXS)
   ECBS.FragSize = LEN(IPXS)

   CALL SendPacket(SendCompleteCode, SendInUseFlag)
   TX.Print "Broadcast packet was sent."

   DO
    CALL RelenquishControl
    SendInUseFlag = ASC(ECBS.InUse)
   LOOP WHILE SendInUseFlag = &HFF

   IF SendInUseFlag <> 0 THEN
    TX.Print "Send error: " + HEX$(SendInUseFlag)
    FOR s = 1 TO 2
     CALL CloseSocket(Socket(s))
    NEXT
    GOSUB GMErrorExit
   END IF

   ECBR.ESRAddressOff = 0
   ECBR.ESRAddressSeg = 0
   ECBR.SockNum = Socket(2)
   ECBR.FragCount = 1
   ECBR.FragAddOfs = VARPTR(IPXR)
   ECBR.FragAddSeg = VARSEG(IPXR)
   ECBR.FragSize = LEN(IPXR)

   CALL SocketListen

   TX.Print "Listening. Hit any key to quit."
   Ti# = TIMER
    DO
     ListenInUseFlag = ASC(ECBR.InUse)
     IF ListenInUseFlag = 0 THEN EXIT DO
     IF INKEY$ <> "" THEN EXIT DO
     IF TIMER >= (Ti# + 3) THEN
   
     CALL IPXCancelR(CompleteCode%)
     CALL IPXCancelS(CompleteCode%)
   
     IF Send = Socket(1) THEN
       Send = Socket(2)
       Listen = Socket(1)
      ELSE
       Send = Socket(1)
       Listen = Socket(2)
     END IF
    
     ECBR.SockNum = Listen
     CALL SocketListen
    
     IPXS.DestSocket = MKI$(Send)
     ECBS.SockNum = Send
     Ti# = TIMER
     CALL SendPacket(SendCompleteCode, SendInUseFlag)
     DO
      CALL RelenquishControl
      SendInUseFlag = ASC(ECBS.InUse)
     LOOP WHILE SendInUseFlag = &HFF
    END IF
   LOOP

   TX.Print ""

   IF ListenInUseFlag <> 0 THEN
    TX.Print "User canceled listen."
    FOR s = 1 TO 2
     CALL CloseSocket(Socket(s))
    NEXT
    GOSUB GMErrorExit
   END IF
  
   SNet$ = TurnToHex$(IPXR.SourNet)
   SNode$ = TurnToHex$(IPXR.SourNode)
   SSoc$ = TurnToHex$(IPXR.SourSock)
  
   IF IPXR.SourSock = MKI$(Socket(1)) THEN
     Send = Socket(2)
     Listen = Socket(1)
    ELSE
     Send = Socket(1)
     Listen = Socket(2)
   END IF
 
   IPXS.Datagram = CHR$(13)
   IPXS.DestSocket = MKI$(Send)
   ECBS.SockNum = Send

   CALL SendPacket(SendCompleteCode, SendInUseFlag)
   TX.Print "Connection established."
  
   DO
    CALL RelenquishControl
    SendInUseFlag = ASC(ECBS.InUse)
   LOOP WHILE SendInUseFlag = &HFF

   DNode$ = IPXR.SourNode
   DNet$ = IPXR.SourNet
   DIAdd$ = ECBR.ImmAdd

   IF Send > Listen THEN
    Control(1) = CONTRL.HERE
    Control(2) = CONTRL.THERE
     ELSE
    Control(1) = CONTRL.THERE
    Control(2) = CONTRL.HERE
   END IF

   MConnectionEstablished = -1

   CALL IPXCancelR(CompleteCode%)
   CALL IPXCancelS(CompleteCode%)

   IPXR.Datagram = CHR$(0)

  CASE MPLAY.TCP     ' TPC/IP Connection Routine
   mul = 2
  CASE MPLAY.MODEM   ' MODEM Connection Routine
 END SELECT

 TX.Print "Using level " + MPlay.LevelName + "."

 ScoreWin = 0

 TX.Print "Game starts in 5 seconds.."

 Delay 5

 Arena.Ang = 0

 check = 0

 MyShip.Model = dIs(1)
 MyShip.Y = 100
 MyShip.AngOff = 90
 MyShip.Ang = 94
 MyShip.Scale = .5
 MyShip.Speed = 0
 O2D.GetRadius MyShip

 MyShips(1) = MyShip
 MyShips(2) = MyShip

 MyShips(1).Colour = 32: Flags(1).Colour = 32
 MyShips(2).Colour = 191: Flags(2).Colour = 191

 MyShips(1).X = MPlaySpawnPoints.X1: MyShips(1).Y = MPlaySpawnPoints.Y1
 MyShips(2).X = MPlaySpawnPoints.X2: MyShips(2).Y = MPlaySpawnPoints.Y2

 MAXWEP(1) = MAXMISSILES
 MAXWEP(2) = MAXMISSILES
 PWep(1) = MissileTemplate
 PWep(2) = MissileTemplate
 PRJ.ClearProjectiles P1Wep(), MAXWEP(1)
 PRJ.ClearProjectiles P2Wep(), MAXWEP(2)

 SetNumlocks
 InitKbd VARSEG(XKey%(0)), VARPTR(XKey%(0))
 FOR I = 1 TO 128: XKey(I) = 0: NEXT I
 
 CSSetTimer 0, 25

 Time = MPlay.TimeLimit

 Score(1) = 0: Score(2) = 0

 StartTime# = TIMER

 ResetStuff# = TIMER

 LOAD.InitVideo

 DO
  CSWaitTimer 0

  IF TIMER - ResetStuff# > 65 THEN
   CSResetTicks 0
   ResetStuff# = TIMER
  END IF

  CSClear EMS.Layer, 0

  DoStars

  OTimeLeft = TimeLeft
  TimeLeft = INT(Time - (TIMER - StartTime#))
  IF Time = -1 THEN TimeLeft = 100

  IF TimeLeft < 6 AND (OTimeLeft <> TimeLeft) THEN
   PRT.ImplodeText LTRIM$(STR$(TimeLeft)) + "!", 160, 100, 4
  END IF

  check = check + 1
  FOR I = 1 TO 2
 
   IF ((check = 2) OR (MIPX.TCP.MODEM <> MPLAY.TCP)) AND NOT Quitter THEN
    GetInput I, Up, Left, Down, Right, Brake, Shoot, Quit
  
    IF Quit THEN Quitter = -1: GOTO GMErrorExit
    IF Shoot THEN  ELSE keyon(I) = 0
    IF Left THEN MyShips(I).Ang = MyShips(I).Ang - 9 * mul
    IF Right THEN MyShips(I).Ang = MyShips(I).Ang + 9 * mul
    IF Up THEN MyShips(I).Speed = MyShips(I).Speed + .6 * mul
    IF Down THEN MyShips(I).Speed = MyShips(I).Speed - .6 * mul
    IF Brake THEN MyShips(I).Speed = MyShips(I).Speed + (-MyShips(I).Speed / (10 / mul))
    IF Shoot AND NOT keyon(I) THEN
     IF I = 1 THEN
       PRJ.AddProjectile P1Wep(), MyShips(1), PWep(1), MAXWEP(1)
      ELSEIF I = 2 THEN
       PRJ.AddProjectile P2Wep(), MyShips(2), PWep(2), MAXWEP(2)
     END IF
     MakeWeaponSound PWep(I).Si
     keyon(I) = -1
    END IF
    IF MPlay.GameType = MPLAYGT.DM THEN
      O2D.MTScreen MyShips(I)
     ELSEIF MPlay.GameType = MPLAYGT.CTF THEN
      IF MyShips(I).X > 320 THEN MyShips(I).X = 320
      IF MyShips(I).X < 1 THEN MyShips(I).X = 1
      IF MyShips(I).Y > 200 THEN MyShips(I).Y = 200
      IF MyShips(I).Y < 1 THEN MyShips(I).Y = 1
    END IF
 
   END IF
 
   IF MyShips(I).Speed > 2.6 THEN MyShips(I).Speed = 2.6
   IF MyShips(I).Speed < -2.6 THEN MyShips(I).Speed = -2.6
   IF ABS(MyShips(I).Speed) < .6 THEN MyShips(I).Speed = 0
  
   OldX(I) = MyShips(I).X
   OldY(I) = MyShips(I).Y
 
   O2D.Check MyShips(I)
  
   O2D.Draw MyShips(I)
   O2D.Propell MyShips(I), MyShips(I).Speed
  
   IF OldX(I) <> MyShips(I).X OR OldY(I) <> MyShips(I).Y THEN
    A = ((MyShips(I).Ang + MyShips(I).AngOff + 90 + 720) MOD 360)
    NewX = MyShips(I).X + (MyShips(I).X - OldX(I)) + ((MyShips(I).Radius * MyShips(I).Scale) * Cosine(A))
    NewY = MyShips(I).Y + (MyShips(I).Y - OldY(I)) + ((MyShips(I).Radius * MyShips(I).Scale) * Sine(A))
    R = RND
    R = R - (R / 2)
    AddLight INT(NewX), INT(NewY), 20, 32
    PRT.AddPart INT(NewX), INT(NewY), -((MyShips(I).X - OldX(I)) / 5) + R, -((MyShips(I).Y - OldY(I)) / 5) + R, 3, 10, 0, Red, 0
    IF O2D.Collide(MyShips(I), Arena, Dx, DY) THEN
     MyShips(I).X = OldX(I)
     MyShips(I).Y = OldY(I)
   
     MyShips(I).Speed = -(MyShips(I).Speed / 2)
    END IF
   END IF

   IF I = 1 THEN
    PRJ.CheckCollide P1Wep(), Arena, MAXWEP(I), Dx, DY, dj
    PRJ.CheckCollide P1Wep(), MyShips(2), MAXWEP(I), Dx, DY, osj
    IF MPlay.GameType = MPLAYGT.CTF THEN
     IF O2D.RadiusCollide(Flags(2), MyShips(1)) THEN
       Flags(2).X = MyShips(1).X: Flags(2).Y = MyShips(1).Y
      ELSE
       Flags(2).X = MPlaySpawnPoints.X2: Flags(2).Y = MPlaySpawnPoints.Y2
     END IF
    END IF
     ELSE
    PRJ.CheckCollide P2Wep(), Arena, MAXWEP(I), Dx, DY, dj
    PRJ.CheckCollide P2Wep(), MyShips(1), MAXWEP(I), Dx, DY, osj
    IF MPlay.GameType = MPLAYGT.CTF THEN
     IF O2D.RadiusCollide(Flags(1), MyShips(2)) THEN
       Flags(1).X = MyShips(2).X: Flags(1).Y = MyShips(2).Y
      ELSE
       Flags(1).X = MPlaySpawnPoints.X1: Flags(1).Y = MPlaySpawnPoints.Y1
     END IF
    END IF
   END IF

   IF dj OR osj THEN
    IF NOT dj AND osj THEN dj = osj
    IF I = 1 THEN
     P1Wep(dj).Active = 0
      ELSE
     P2Wep(dj).Active = 0
    END IF
    DS4QB.PlaySoundEx 2, CURRENT, CURRENT, CURRENT, CURRENT
    PRT.CircleExp Dx, DY, 15, 2, 0
    IF osj THEN
     SELECT CASE MPlay.GameType
      CASE MPLAYGT.DM
       Score(I) = Score(I) + 1
      CASE MPLAYGT.CTF
        PRT.ImplodeText "BOOM!", Dx, DY, 1
       SELECT CASE I
        CASE 1
         Flags(1).X = MPlaySpawnPoints.X1: Flags(1).Y = MPlaySpawnPoints.Y1
         MyShips(2).X = MPlaySpawnPoints.X2: MyShips(2).Y = MPlaySpawnPoints.Y2
        CASE 2
         Flags(2).X = MPlaySpawnPoints.X2: Flags(2).Y = MPlaySpawnPoints.Y2
         MyShips(1).X = MPlaySpawnPoints.X1: MyShips(1).Y = MPlaySpawnPoints.Y1
       END SELECT
     END SELECT
    END IF
   END IF

   IF Score(I) >= MPlay.ScoreLimit AND MPlay.ScoreLimit <> -1 THEN TimeLeft = -1: Winner = I

  NEXT I

  IF O2D.RadiusCollide(Flags(1), Flags(2)) THEN
   IF Flags(1).X = MPlaySpawnPoints.X1 AND Flags(1).Y = MPlaySpawnPoints.Y1 THEN
     Score(1) = Score(1) + 1
     Flags(2).X = MPlaySpawnPoints.X2: Flags(2).Y = MPlaySpawnPoints.Y2
     PRT.ImplodeText "C-T-F!", 160, 100, 2
    ELSEIF Flags(2).X = MPlaySpawnPoints.X2 AND Flags(2).Y = MPlaySpawnPoints.Y2 THEN
     Score(2) = Score(2) + 1
     Flags(1).X = MPlaySpawnPoints.X1: Flags(1).Y = MPlaySpawnPoints.Y1
     PRT.ImplodeText "C-T-F!", 160, 100, 2
   END IF
  END IF

  IF check = 2 THEN check = 0

  PRJ.MoveAndDrawProjectiles P1Wep(), MAXWEP(1)
  PRJ.MoveAndDrawProjectiles P2Wep(), MAXWEP(2)

  SELECT CASE MPlay.GameType
   CASE MPLAYGT.DM
   CASE MPLAYGT.CTF
    FOR I = 1 TO 2
     O2D.Check Flags(I)
     O2D.Draw Flags(I)
    NEXT I
  END SELECT

  O2D.Draw Arena

  PRT.MoveAndDrawParticles

  FOR I = 1 TO 2
   IF Score(I) = MPlay.ScoreLimit THEN ScoreWin = -1
  NEXT I

  IF Time <> -1 THEN TX.Locate 24: TX.CPrint " Time left:" + STR$(TimeLeft)
  TX.Locate 25: TX.CPrint "Player 1 Score:" + STR$(Score(1)) + " Player 2 Score:" + STR$(Score(2))
  A$ = LTRIM$(RTRIM$(MPlay.Name))
  TX.Locate 1: TX.CPrint A$
  IF TIMER - st# >= 1 THEN FPS = FPSCount: st# = TIMER: FPSCount = 0

  CSPcopy EMS.Layer, &HA000
  FPSCount = FPSCount + 1
 LOOP UNTIL Quitter OR TimeLeft = 0 OR ScoreWin

 DeinitKbd

 Quiter# = TIMER
 CSSetTimer 0, 25

 DO
  CSWaitTimer 0
  CSClear EMS.Layer, 0

  Explosions st#

  DoStars

  PRT.MoveAndDrawParticles

  TX.Locate 9

  TX.CPrint "Game Over!"
  TX.CPrint "": TX.CPrint ""

  IF Score(1) > Score(2) THEN TX.CPrint "Player 1 Wins!!!"
  IF Score(2) > Score(1) THEN TX.CPrint "Player 2 Wins!!!"
  IF Score(1) = Score(2) THEN TX.CPrint "Draw."
  
  TX.CPrint "Player 1's Score :" + STR$(Score(1))
  TX.CPrint "Player 2's Score :" + STR$(Score(2))
  
  TX.CPrint "": TX.CPrint ""

  TX.CPrint "Hit any key to continue..."

  CSPcopy EMS.Layer, &HA000

 LOOP UNTIL INKEY$ <> "" AND TIMER - Quiter# > 2
 
 FOR I = 1 TO 2
  CloseSocket Socket(I)
 NEXT I

 EXIT SUB

GMErrorExit:
 DeinitKbd
 TX.Print "Game interuptted. (press a key)"
 G$ = INPUT$(1)
 CSClear EMS.Layer, 0

 PRT.ClearAllParts

 IF MConnectionEstablished THEN
  FOR I = 1 TO 2
   CloseSocket Socket(I)
  NEXT I
 END IF

END SUB

SUB GAME.ScoreMode (Score AS LONG, KillEff#, TotalTime#)
 DIM RmlHave AS Object2D

 DJNo = 2

 FOR I = 1 TO 7
  HaveWeapon(I) = 1
 NEXT I
 PRT.ClearAllParts

 MyShip.Model = dIs(1)
 MyShip.X = 160
 MyShip.Y = 100
 MyShip.AngOff = 90
 MyShip.Ang = 90
 MyShip.Scale = .5
 MyShip.Speed = 0
 O2D.GetRadius MyShip
 MyShipProt = MyShip
 MyShipProt.Radius = MyShipProt.Radius * 3

 SetCam (MyShip.X), (MyShip.Y), 2: ZoomF! = 1.5

 FOR I = 1 TO MAXASTERIODS
  Asteriods(I).Model = dIs(2)
  DO
   Asteriods(I).X = RND * 320: Asteriods(I).Y = RND * 200
   IF NOT O2D.RadiusCollide(Asteriods(I), MyShipProt) OR Asteriods(I).X <> MyShipProt.X AND Asteriods(I).Y <> MyShipProt.Y THEN EXIT DO
  LOOP
  Asteriods(I).Ang = RND * 360
  Asteriods(I).Scale = .45
  Asteriods(I).Radius = Asteriods(1).Radius
  Asteriods(I).Colour = 230
 NEXT I

 PRT.ClearAllParts

 PRJ.ClearProjectiles Missile(), MAXMISSILES
 PRJ.ClearProjectiles Laser(), MAXLASERS
 PRJ.ClearProjectiles CBomb(), MAXCBOMBS
 PRJ.ClearProjectiles CMiniBomb(), MAXCMINIBOMBS
 PRJ.ClearProjectiles Beam(), MAXBEAMS
 PRJ.ClearProjectiles Mine(), MAXMINES
 PRJ.ClearProjectiles Mini(), MAXMINIS
 PRJ.ClearProjectiles Rml5K(), MAXRML5K
 PRJ.ClearProjectiles Rml5KMini(), MAXRMLMINIS

 T = 60
 Continue = 0
 st# = TIMER
 CSSetTimer 0, 25

 DO
  CSWaitTimer 0

  CSClear EMS.Layer, 0

  Explosions st#

  DoStars

  PRT.MoveAndDrawParticles

  k$ = ""
  FOR I = 1 TO 16
   G$ = INKEY$
   IF G$ <> "" AND TIMER - pauseK# > .1 THEN k$ = G$: pauseK# = TIMER
  NEXT I
 
  TX.Locate 11
  Text.Colour = 255
  TX.CPrint "Please specify the time limit.": TX.CPrint ""
  TX.CPrint "Use [UP] and [DOWN] to change it,": TX.CPrint ""
  TX.CPrint "and hit [ENTER] set it as that.": TX.CPrint ""
  Text.Colour = 230
  T$ = STR$(T): IF T = 0 THEN T$ = " No time limit."
  TX.CPrint "-->" + T$ + " <--"
  Text.Colour = 255

  SELECT CASE k$
   CASE CHR$(0) + "P"
    T = T - 10
    DS4QB.PlaySoundEx 7, 44050, CURRENT, CURRENT, CURRENT
   CASE CHR$(0) + "H"
    T = T + 10
    DS4QB.PlaySoundEx 7, 44050, CURRENT, CURRENT, CURRENT
   CASE CHR$(13)
    DS4QB.PlaySoundEx 4, 22050, CURRENT, CURRENT, CURRENT
    Continue = -1
   CASE CHR$(27)
    DS4QB.PlaySoundEx 4, 22050, CURRENT, CURRENT, CURRENT
    EXIT SUB
  END SELECT

  IF T > 1000 THEN T = 1000
  IF T < 1 THEN T = 0
 
  CSPcopy EMS.Layer, &HA000
 LOOP UNTIL Continue

 IF T = 0 THEN T = -1

 Time = T

 IF Time = 0 THEN Time = 60

 RmlHave = Rml5KTemplate.Object
 RmlHave.X = 10
 RmlHave.Y = 190

 IF gOk THEN DoubleScore = 1 ELSE DoubleScore = 0
 Score = 0

 st# = TIMER

 DIM OldX AS SINGLE, OldY AS SINGLE, R AS SINGLE
 DIM NewX AS SINGLE, NewY AS SINGLE

 SetNumlocks
 InitKbd VARSEG(XKey%(0)), VARPTR(XKey%(0))
 FOR I = 1 TO 128: XKey%(I) = 0: NEXT I
 
 CSSetTimer 0, 25

 st1# = TIMER
 DO
  CSWaitTimer 0
  CSClear EMS.Layer, 0
  PRT.MoveAndDrawParticles
  IF (TIMER - st1#) > .05 THEN tICK = (tICK + 1) AND 1: IF tICK THEN Text.Colour = Text.Colour - 1
  TX.Locate 13
  TX.CPrint "Ready..."
  CSPcopy EMS.Layer, &HA000
 LOOP UNTIL Text.Colour < 195
 st1# = TIMER
 Text.Colour = 255
 DO
  CSWaitTimer 0
  CSClear EMS.Layer, 0
  PRT.MoveAndDrawParticles
  IF (TIMER - st1#) > .05 THEN Text.Colour = Text.Colour - 1
  TX.Locate 13
  TX.CPrint "SET..."
  CSPcopy EMS.Layer, &HA000
 LOOP UNTIL Text.Colour < 198
 Text.Colour = 255
 FOR I = 1 TO 3
  st1# = TIMER
  PRT.ImplodeText "GO!", 125 + (I * 30) - 30, 100, 3
  DO
   CSWaitTimer 0
   CSClear EMS.Layer, 0
   PRT.MoveAndDrawParticles
   CSPcopy EMS.Layer, &HA000
  LOOP UNTIL TIMER - st1# > .35
 NEXT I

 RANDOMIZE TIMER

 UfoActive = 0

 CurrentWeapon = 1

 StartTime# = TIMER

 UfoGO# = TIMER

 HaveWeapon(7) = 0

 FOR I = 1 TO MAXASTERIODS
  SpawnEnemy Asteriods(I)
 NEXT
 
 DO
  CSWaitTimer 0

  IF TIMER - UfoGO# > 10 THEN
   UfoGO# = TIMER
   IF UfoActive = 0 THEN
    Ufo.X = -(Ufo.Radius * Ufo.Scale)
    Ufo.Y = RND * 200
    UfoActive = -1
   END IF
  END IF

  CSClear EMS.Layer, 0

  DoStars

  OScore = PScore

  OTimeLeft = TimeLeft
  TimeLeft = INT(Time - (TIMER - StartTime#))
  IF Time = -1 THEN TimeLeft = 100

  IF TimeLeft < 6 AND (OTimeLeft <> TimeLeft) THEN
   PRT.ImplodeText LTRIM$(STR$(TimeLeft)) + "!", 160, 100, 3
  END IF

  IF TIMER - st# >= 1 THEN FPS = FPSCount: st# = TIMER: FPSCount = 0

  IF XKey(&H39) THEN  ELSE keyon = 0

  OldX = MyShip.X
  OldY = MyShip.Y

  FOR I = &H2 TO &H8
   IF XKey(I) AND HaveWeapon(I - 1) THEN CurrentWeapon = I - 1
  NEXT I

  UpDown = 0

  IF XKey(SPlayerC.Left) THEN MyShip.Ang = MyShip.Ang - 9: O2D.Check MyShip
  IF XKey(SPlayerC.Right) THEN MyShip.Ang = MyShip.Ang + 9: O2D.Check MyShip
  IF XKey(SPlayerC.Up) THEN MyShip.Speed = MyShip.Speed + .3: UpDown = -1
  IF XKey(SPlayerC.Down) THEN MyShip.Speed = MyShip.Speed - .3: UpDown = -2
  IF XKey(SPlayerC.Brake) THEN MyShip.Speed = MyShip.Speed + (-MyShip.Speed / 10)

  IF XKey(SPlayerC.Shoot) THEN IF NOT keyon THEN FireWeapon CurrentWeapon: keyon = -1: IF CurrentWeapon = 7 THEN CurrentWeapon = 6: HaveWeapon(7) = 0

  IF ABS(MyShip.Speed) < .3 THEN MyShip.Speed = 0

  IF MyShip.Speed > 2.6 THEN MyShip.Speed = 2.6
  IF MyShip.Speed < -2.6 THEN MyShip.Speed = -2.6

  O2D.MTScreen MyShip
  O2D.Propell MyShip, MyShip.Speed
  O2D.Draw MyShip

  IF (MyShip.X <> OldX OR MyShip.Y <> OldY OR UpDown) THEN
   A = ((MyShip.Ang + MyShip.AngOff + 90 + 720) MOD 360)
   AddLight INT(MyShip.X + ((MyShip.X - OldX) \ 2) + ((MyShip.Radius * MyShip.Scale) * Cosine(A))), INT(MyShip.Y + ((MyShip.Y - OldY) \ 2) + ((MyShip.Radius * MyShip.Scale) * Sine(A))), 20, 32
   NewX = MyShip.X + (MyShip.X - OldX) + ((MyShip.Radius * MyShip.Scale) * Cosine(A))
   NewY = MyShip.Y + (MyShip.Y - OldY) + ((MyShip.Radius * MyShip.Scale) * Sine(A))
   R = RND
   R = R - (R / 2)
   PRT.AddPart INT(NewX), INT(NewY), -((MyShip.X - OldX) / 10) + R, -((MyShip.Y - OldY) / 10) + R, 3, 20, 0, Red, 0
  END IF

  FOR I = 1 TO MAXASTERIODS / DJNo
   Asteriods(I).AngOff = Asteriods(I).AngOff + 5
   O2D.Check Asteriods(I)
   IF TIMER - ls#(I) > 5 THEN O2D.Propell Asteriods(I), 4 / DJNo: ls#(I) = 0
   O2D.MTScreen Asteriods(I)

   PRJ.CheckCollide Missile(), Asteriods(I), MAXMISSILES, Dx, DY, cm
   PRJ.CheckCollide Laser(), Asteriods(I), MAXLASERS, Dx, DY, cml
   PRJ.CheckCollide CBomb(), Asteriods(I), MAXCBOMBS, Dx, DY, cbm
   PRJ.CheckCollide CMiniBomb(), Asteriods(I), MAXCMINIBOMBS, Dx, DY, cmbm
   PRJ.CheckCollide Beam(), Asteriods(I), MAXBEAMS, Dx, DY, cbam
   PRJ.CheckCollide Mine(), Asteriods(I), MAXMINES, Dx, DY, cmin
   PRJ.CheckCollide Mini(), Asteriods(I), MAXMINIS, Dx, DY, cmii
   PRJ.CheckCollide Rml5K(), Asteriods(I), MAXRML5K, Dx, DY, cmrm
   PRJ.CheckCollide Rml5KMini(), Asteriods(I), MAXRMLMINIS, Dx, DY, cmrmn

   IF cml THEN
    PRT.CircleExp Dx, DY, 6, 2, 0
    ls#(I) = TIMER
    Laser(cml).Active = 0
   END IF

   sm = O2D.Collide(MyShip, Asteriods(I), dxs, dys)
   IF sm AND ls#(I) = 0 THEN hurtTheShip = hurtTheShip + 3
   IF sm OR cm OR cbm OR cmbm OR cbam OR cmin OR cmii OR cmrm OR cmrmn THEN
 
    IF NOT sm THEN Score = Score + 1 + DoubleScore ELSE Dx = dxs: DY = dxy

    IF cm THEN Missile(cm).Active = 0: Score = Score + 1
    IF cbm THEN CBomb(cbm).Active = 0: HandleCBExp cbm, Dx, DY
    IF cmbm THEN CMiniBomb(cmbm).Active = 0
    IF cmin THEN Mine(cmin).Active = 0: Score = Score + 1
    IF cmii THEN Mini(cmii).Active = 0
    IF cmrm THEN PRT.CircleExp INT(Rml5K(cmrm).Object.X), INT(Rml5K(cmrm).Object.Y), 20, 2, 0: Rml5K(cmrm).Active = 0
    IF cmrmn THEN Rml5KMini(cmrmn).Active = 0
  
    PRT.CircleExp INT(Asteriods(I).X), INT(Asteriods(I).Y), 30, 2, 0
    IF NOT sm THEN PRT.ImplodeText "BOOM!", Dx, DY, 1
    MyShipProt = MyShip
    MyShipProt.Radius = MyShipProt.Radius * 3
    IF TIMER - ls#(I) < 6 AND ls#(I) <> 0 THEN Score = Score + 1 + DoubleScore: PRT.ImplodeText "+2!", 160, 100, 2
    ls#(I) = 0
    DS4QB.PlaySoundEx 1, 8000, CURRENT, CURRENT, CURRENT
    DO
     Asteriods(I).X = RND * 320: Asteriods(I).Y = RND * 200
     IF NOT O2D.RadiusCollide(Asteriods(I), MyShipProt) AND Asteriods(I).X <> MyShip.X AND Asteriods(I).Y <> MyShip.Y THEN EXIT DO
    LOOP
    SpawnEnemy Asteriods(I)
   END IF
   O2D.Draw Asteriods(I)
  NEXT I

  IF UfoActive THEN

   OldX = Ufo.X: OldY = Ufo.Y
   IF uls# = 0 THEN Ufo.X = Ufo.X + Ufo.Speed ELSE Ufo.X = Ufo.X + (Ufo.Speed / (uls# * 2))

   PRJ.CheckCollide Missile(), Ufo, MAXMISSILES, Dx, DY, cm
   PRJ.CheckCollide Laser(), Ufo, MAXLASERS, Dx, DY, cml
   PRJ.CheckCollide CBomb(), Ufo, MAXCBOMBS, Dx, DY, cbm
   PRJ.CheckCollide CMiniBomb(), Ufo, MAXCMINIBOMBS, Dx, DY, cmbm
   PRJ.CheckCollide Beam(), Ufo, MAXBEAMS, Dx, DY, cbam
   PRJ.CheckCollide Mine(), Ufo, MAXMINES, Dx, DY, cmin
   PRJ.CheckCollide Mini(), Ufo, MAXMINIS, Dx, DY, cmii
   PRJ.CheckCollide Rml5K(), Ufo, MAXRML5K, Dx, DY, cmrm
   PRJ.CheckCollide Rml5KMini(), Ufo, MAXRMLMINIS, Dx, DY, cmrmn

   IF cml THEN
    PRT.CircleExp Dx, DY, 6, 2, 0
    uls# = TIMER
    Laser(cml).Active = 0
   END IF

   IF TIMER - uls# > 6 THEN uls# = 0
   sm = O2D.Collide(MyShip, Ufo, dxs, dys)
   IF sm AND uls# = 0 THEN hurtTheShip = hurtTheShip + 9
   IF sm OR cm OR cbm OR cmbm OR cbam OR cmin OR cmii OR cmrm OR cmrmn THEN

    IF NOT sm THEN Score = Score + 2 + DoubleScore ELSE Dx = dxs: DY = dxy
    IF sm AND uls# <> 0 THEN HaveWeapon(7) = -1: PRT.ImplodeText "RML!", (Ufo.X), Ufo.Y - 20, 2

    IF cm THEN Missile(cm).Active = 0
    IF cbm THEN CBomb(cbm).Active = 0: HandleCBExp cbm, Dx, DY
    IF cmbm THEN CMiniBomb(cmbm).Active = 0
    IF cmin THEN Mine(cmin).Active = 0
    IF cmii THEN Mini(cmii).Active = 0
    IF cmrm THEN PRT.CircleExp INT(Rml5K(cmrm).Object.X), INT(Rml5K(cmrm).Object.Y), 20, 2, 0: Rml5K(cmrm).Active = 0
    IF cmrmn THEN Rml5KMini(cmrmn).Active = 0

    PRT.CircleExp INT(Ufo.X), INT(Ufo.Y), 30, 2, 0
    IF NOT sm THEN PRT.ImplodeText "BOOM!", Dx, DY, 1
    IF TIMER - uls# < 6 AND uls# <> 0 THEN Score = Score + 2 + DoubleScore: PRT.ImplodeText "+2!", 160, 100, 2
    uls# = 0
    DS4QB.PlaySoundEx 1, CURRENT, CURRENT, CURRENT, CURRENT
    UfoActive = 0
   END IF

   O2D.Check Ufo
   O2D.Draw Ufo
   
   A = 180
   NewX = Ufo.X + (Ufo.X - OldX) + ((Ufo.Radius * Ufo.Scale) * Cosine(A))
   NewY = Ufo.Y + (Ufo.Y - OldY) + ((Ufo.Radius * Ufo.Scale) * Sine(A))
   R = RND
   R = R - (R / 2)
   AddLight INT(NewX), INT(NewY), 25, 96
   IF uls# = 0 THEN
    PRT.AddPart INT(NewX), INT(NewY), -((Ufo.X - OldX) / 10) + R, -((Ufo.Y - OldY) / 10) + R, 3, 20, 0, Green, 0
   END IF

   IF Ufo.X - (Ufo.Radius * Ufo.Scale) > 320 THEN UfoActive = 0

  END IF

  PRJ.CheckCollide CMiniBomb(), MyShip, MAXCMINIBOMBS, Dx, DY, cm
  IF cm THEN hurtTheShip = hurtTheShip + 1: CMiniBomb(cm).Active = 0: PRT.CircleExp Dx, DY, 12, 2, 0
  PRJ.CheckCollide Mine(), MyShip, MAXMINES, Dx, DY, cm
  IF cm THEN hurtTheShip = hurtTheShip + 1: Mine(cm).Active = 0: PRT.CircleExp Dx, DY, 12, 2, 0

  IF hurtTheShip THEN
   Score = Score - hurtTheShip
   PRT.ImplodeText "OWCH!", INT(MyShip.X), INT(MyShip.Y), 1
  END IF

  hurtTheShip = 0

  PRJ.MoveAndDrawProjectiles Missile(), MAXMISSILES
  PRJ.MoveAndDrawProjectiles Laser(), MAXLASERS
  PRJ.MoveAndDrawProjectiles CBomb(), MAXCBOMBS
  PRJ.MoveAndDrawProjectiles CMiniBomb(), MAXCMINIBOMBS
  PRJ.MoveAndDrawProjectiles Beam(), MAXBEAMS
  PRJ.MoveAndDrawProjectiles Mine(), MAXMINES
  PRJ.MoveAndDrawProjectiles Mini(), MAXMINIS
  PRJ.MoveAndDrawProjectiles Rml5K(), MAXRML5K
  PRJ.MoveAndDrawProjectiles Rml5KMini(), MAXRMLMINIS

  HandleRML5K

  IF HaveWeapon(7) THEN
   RmlHave.Ang = RmlHave.Ang + 10
   O2D.Check RmlHave
   O2D.Draw RmlHave
  END IF

  IF ZoomF! > 1 THEN ZoomF! = ZoomF! - .035
  IF ZoomF! < 1 THEN ZoomF! = 1

  SetCam (MyShip.X), (MyShip.Y), ZoomF!

  PRT.MoveAndDrawParticles

  Text$ = "Score:" + STR$(Score)
  IF Time <> -1 THEN Text$ = Text$ + ", Time left:" + STR$(TimeLeft) ELSE Text$ = Text$ + " Time ellapsed:" + STR$(INT(TIMER - StartTime#))
  CSPrint EMS.Layer, 160 - (CSLen(Text$) / 2), 0, Text$, 255

  CSPcopy EMS.Layer, &HA000
  FPSCount = FPSCount + 1
 LOOP UNTIL XKey(&H1) OR TimeLeft <= 0

 DeinitKbd

 TotalTime# = (TIMER - StartTime#) + 1
 Ke! = Score / TotalTime#
 Score = (Ke! / 3.5) * 100  ' 3.5 being what I think is the 'ultimate score'

 Quiter# = TIMER
 CSSetTimer 0, 25

 DO
  CSWaitTimer 0
  CSClear EMS.Layer, 0

  Explosions st#

  DoStars
 
  PRT.MoveAndDrawParticles
  
  TX.Locate 9
  TX.CPrint "Game Over!"
  TX.CPrint "": TX.CPrint ""

  TX.CPrint "Your final score:" + STR$(Score)
  TX.CPrint "(" + LTRIM$(STR$(INT(TotalTime#))) + " Seconds)"
  TX.CPrint "(kill effitancey :" + STR$(INT(Ke! * 1000) / 1000) + ")"

  TX.CPrint "": TX.CPrint ""
  IF Score <= 0 THEN TX.CPrint "WOW! You suck!"
  IF Score > 0 AND Score <= 33 THEN TX.CPrint "You were ok."
  IF Score > 33 AND Score <= 66 THEN TX.CPrint "Getting better."
  IF Score > 66 AND Score <= 100 THEN TX.CPrint "Not bad!"
  IF Score > 100 THEN TX.CPrint "You are 3l33t! :]"

  CSPcopy EMS.Layer, &HA000

 LOOP UNTIL INKEY$ <> "" AND TIMER - Quiter# > 2

 KillEff# = INT(Ke! * 1000) / 1000

 PRT.ClearAllParts

 CSClear EMS.Layer, 0

 DoHighScores KillEff#, DHS.ADD
END SUB

SUB LoadLMLevel (FileName AS STRING)
 F = FREEFILE
 OPEN "Levels\Main\" + FileName FOR INPUT AS #F
  INPUT #F, HEHEH.HE.HEHE...HEHE
  INPUT #F, ScoreWinNeed
  INPUT #F, NofE
  ScoreWin = 0
  FOR I = 1 TO NofE
   INPUT #F, EnemyNum
   Enemys(I) = EnemyTemplate(EnemyNum)
   Enemys(I).Used = -1
   Enemys(I).Status = 1
   INPUT #F, Enemys(I).Object.X, Enemys(I).Object.Y, Enemys(I).Object.Ang
   ScoreWin = ScoreWin + Enemys(I).Score
  NEXT I
 CLOSE #F
END SUB

FUNCTION PlayLevel (Wave, Level, NetScore)

 DIM wepHave(1 TO 8) AS STRING
 DIM Score AS DOUBLE, EScore AS DOUBLE, OEScore AS DOUBLE
 DIM turnVOL AS DOUBLE

 SetCam 160, 100, 1: ZoomF! = 1

 FOR I = 1 TO MAXENEMYS
  Enemys(I).Used = 0
 NEXT I

 turnVOL = 0

 wepHave(1) = "Blaster"
 wepHave(2) = "Missiles"
 wepHave(3) = "Mines"
 wepHave(4) = "Cluster Mines"
 wepHave(5) = "Freze Laser"
 wepHave(6) = "Hypr Beam"
 wepHave(7) = "Mini Missiles"
 wepHave(8) = "RML 5000"

 PRT.ClearAllParts

 MyShip.X = 160
 MyShip.Y = 100
 MyShip.AngOff = 90
 MyShip.Ang = 90
 MyShip.Scale = .5
 MyShip.Speed = 0
 MyShipProt = MyShip
 MyShipProt.Radius = MyShipProt.Radius * 3

 PRT.ClearAllParts

 PRJ.ClearProjectiles EnemyProjs(), MAXENEMYPROJS

 PRJ.ClearProjectiles LLaser(), MAXLLASERS
 PRJ.ClearProjectiles Missile(), MAXMISSILES
 PRJ.ClearProjectiles Laser(), MAXLASERS
 PRJ.ClearProjectiles CBomb(), MAXCBOMBS
 PRJ.ClearProjectiles CMiniBomb(), MAXCMINIBOMBS
 PRJ.ClearProjectiles Beam(), MAXBEAMS
 PRJ.ClearProjectiles Mine(), MAXMINES
 PRJ.ClearProjectiles Mini(), MAXMINIS
 PRJ.ClearProjectiles Rml5K(), MAXRML5K
 PRJ.ClearProjectiles Rml5KMini(), MAXRMLMINIS

 PWRUP.ClearPowerUps

 ScoreWin = 100

 FileName$ = "XGL" + BlahS$(Wave) + "-" + BlahS$(Level) + ".INF"

 DEB.Clear

 IF Wave = 1 AND Level = 9 THEN
  A# = 0
  astep# = 360 / 10
  FOR shat = 1 TO 10
   A# = A# + astep#
   DEB.Add 160, 100, INT(A#), INT((RND * 2) + 2), .8
  NEXT
  FOR J = 1 TO 200
   FOR I = 1 TO UBOUND(Debris, 1)
    IF Debris(I).Used THEN
     Debris(I).Object.AngOff = Debris(I).Object.AngOff + (Debris(I).Object.Speed * 2)
     O2D.Check Debris(I).Object
     O2D.Propell Debris(I).Object, Debris(I).Object.Speed
     O2D.MTScreen Debris(I).Object
    END IF
   NEXT
  NEXT
 END IF

 LoadLMLevel FileName$

 DIM OldX AS SINGLE, OldY AS SINGLE, R AS SINGLE
 DIM NewX AS SINGLE, NewY AS SINGLE

 InitKbd VARSEG(XKey%(0)), VARPTR(XKey%(0))
 FOR I = 1 TO 128: XKey%(I) = 0: NEXT I
 
 CSSetTimer 0, 35

 RANDOMIZE TIMER

 CurrentWeapon = 1

 OScore = Score
 OEScore = EScore

 Status = 0

 st# = TIMER
 Colour = 193
 DO
  CSWaitTimer 0
  CSClear EMS.Layer, 0
  DoStars
  
  IF Wave = 1 AND Level = 9 THEN DEB.MoveDraw

  O2D.Check MyShip
  O2D.Draw MyShip

  PRT.MoveAndDrawParticles

  FOR I = &H2 TO &H9
   IF XKey(I) AND (HaveWeapon(I - 1) > 0 OR HaveWeapon(I - 1) = -1) THEN CurrentWeapon = I - 1
  NEXT I
  
  IF TIMER - st# < 3 THEN
    Colour = Colour + 1
    IF Colour > 255 THEN Colour = 255
   ELSE
    Colour = Colour - 1
  END IF

  Text.Colour = Colour
  TX.Locate 13: TX.CPrint "Level" + STR$(Wave) + "-" + LTRIM$(STR$(Level))

  GOSUB DrawBars

  CSPcopy EMS.Layer, &HA000
 LOOP UNTIL Colour <= 193

 TurTime# = TIMER

 Starting = -1
 
 DO
  CSWaitTimer 0

  CSClear EMS.Layer, 0

  DoStars

  IF Wave = 1 AND Level = 9 THEN DEB.MoveDraw
  
  allgone = -1
  FOR I = 1 TO MAXENEMYS
   IF Enemys(I).Used THEN
    IF Starting THEN SpawnEnemy Enemys(I).Object
    allgone = 0
   END IF
  NEXT I

  Starting = 0

  IF allgone AND Blah# = 0 AND Status = 0 THEN Blah# = TIMER
  IF Blah# <> 0 AND (TIMER - Blah#) > 6 AND Status = 0 THEN
   IF Score >= (ScoreWin * ScoreWinNeed) THEN
     DS4QB.PlaySoundEx 8, 44040, CURRENT, CURRENT, CURRENT
     Status = 1
    ELSE
     Status = 3
   END IF
  END IF
 
  IF EScore >= ScoreLose THEN Status = 2

  IF XKey(SPlayerC.Shoot) THEN  ELSE keyon = 0

  OldX = MyShip.X
  OldY = MyShip.Y

  FOR I = &H2 TO &H9
   IF XKey(I) AND (HaveWeapon(I - 1) > 0 OR HaveWeapon(I - 1) = -1) THEN CurrentWeapon = I - 1
  NEXT I

  IF Status = 0 THEN

   ZoomF! = ZoomF! + .05
   IF ZoomF! > 1.5 THEN ZoomF! = 1.5

   UpDown = 0
   IF XKey(SPlayerC.Brake) THEN Turbo = 1 ELSE Turbo = 0
   IF XKey(SPlayerC.Left) THEN MyShip.Ang = MyShip.Ang - (9 + (3 * Turbo))
   IF XKey(SPlayerC.Right) THEN MyShip.Ang = MyShip.Ang + (9 + (3 * Turbo))
   IF XKey(SPlayerC.Up) THEN MyShip.Speed = MyShip.Speed + (.3 + (.3 * Turbo)): UpDown = -1
   IF XKey(SPlayerC.Down) THEN MyShip.Speed = MyShip.Speed - (.3 + (.3 * Turbo)): UpDown = -2
   
   O2D.Check MyShip

   IF XKey(SPlayerC.Shoot) AND NOT keyon THEN
    FireWeapon CurrentWeapon - 1: keyon = -1
    IF HaveWeapon(CurrentWeapon) <> -1 THEN
     HaveWeapon(CurrentWeapon) = HaveWeapon(CurrentWeapon) - 1
     DO WHILE HaveWeapon(CurrentWeapon) = 0
      CurrentWeapon = CurrentWeapon - 1
     LOOP
     IF CurrentWeapon < 0 THEN CurrentWeapon = 0
    END IF
   END IF

   IF ABS(MyShip.Speed) < .3 THEN MyShip.Speed = 0
  
   IF Turbo = 0 THEN
     IF MyShip.Speed > 2.6 THEN MyShip.Speed = MyShip.Speed - .6: IF MyShip.Speed < 2.6 THEN MyShip.Speed = 2.6
     IF MyShip.Speed < -2.2 THEN MyShip.Speed = MyShip.Speed + .6: IF MyShip.Speed > -2.2 THEN MyShip.Speed = -2.2
    ELSE
     IF MyShip.Speed > 5.2 THEN MyShip.Speed = 5.2
     IF MyShip.Speed < -4.8 THEN MyShip.Speed = -4.8
   END IF

   O2D.MTScreen MyShip
  END IF

  IF Status THEN
   ZoomF! = ZoomF! - .05
   IF ZoomF! < 1 THEN ZoomF! = 1
  END IF

  IF Status = 1 THEN
   IF Wave = 1 AND Level = 9 THEN
    FOR J = 0 TO 255
     CSGetCol J, Rc, Bc, Gc
     Rc = Rc - 1: Bc = Bc - 1: Gc = Gc - 1
     IF Rc < 0 THEN Rc = 0
     IF Bc < 0 THEN Bc = 0
     IF Gc < 0 THEN Gc = 0
     CSSetCol J, Rc, Bc, Gc
    NEXT J
   END IF

   IF Wave = 1 AND Level = 9 THEN MyShip.Speed = MyShip.Speed + .5 ELSE MyShip.Speed = MyShip.Speed + 1
   IF MyShip.X > 640 + (MyShip.Scale * MyShip.Radius) OR (MyShip.X < -320 - (MyShip.Scale * MyShip.Radius)) OR (MyShip.Y > 400 + (MyShip.Scale * MyShip.Radius)) OR (MyShip.Y < -200 - (MyShip.Scale * MyShip.Radius)) THEN rCode = 1: EXIT DO
  END IF

  IF Status = 2 THEN
   IF blah2# = 0 THEN PRT.CircleExp INT(MyShip.X), INT(MyShip.Y), 100, 2, 0: blah2# = TIMER: DS4QB.PlaySoundEx 1, 8000, CURRENT, CURRENT, CURRENT
   IF blah2# AND (TIMER - blah2#) >= 7 THEN rCode = -1: EXIT DO
  END IF

  O2D.Propell MyShip, MyShip.Speed
  IF Status <> 2 THEN O2D.Draw MyShip

  IF MyShip.X > 300 OR MyShip.X < 20 OR MyShip.Y > 180 OR MyShip.Y < 20 THEN
   ZoomF! = ZoomF! - .1
   IF ZoomF! < 1 THEN ZoomF! = 1
  END IF

  IF (MyShip.X <> OldX OR MyShip.Y <> OldY OR UpDown) AND Status <> 2 THEN
   A = ((MyShip.Ang + MyShip.AngOff + 90 + 720) MOD 360)
   AddLight INT(MyShip.X + ((MyShip.X - OldX) \ 2) + ((MyShip.Radius * MyShip.Scale) * Cosine(A))), INT(MyShip.Y + ((MyShip.Y - OldY) \ 2) + ((MyShip.Radius * MyShip.Scale) * Sine(A))), 20, 32
   NewX = MyShip.X + (MyShip.X - OldX) + ((MyShip.Radius * MyShip.Scale) * Cosine(A))
   NewY = MyShip.Y + (MyShip.Y - OldY) + ((MyShip.Radius * MyShip.Scale) * Sine(A))
   R = RND
   R = R - (R / 2)
   PRT.AddPart INT(NewX), INT(NewY), -((MyShip.X - OldX) / 10) + R, -((MyShip.Y - OldY) / 10) + R, 3, 10, 0, Red, 0
  END IF

  PRJ.CheckCollide CMiniBomb(), MyShip, MAXCMINIBOMBS, Dx, DY, cm
  IF cm THEN hurtTheShip = hurtTheShip + 2: CMiniBomb(cm).Active = 0: PRT.CircleExp Dx, DY, 12, 2, 0
  PRJ.CheckCollide Mine(), MyShip, MAXMINES, Dx, DY, cm
  IF cm THEN hurtTheShip = hurtTheShip + 2: Mine(cm).Active = 0: PRT.CircleExp Dx, DY, 12, 2, 0

  IF hurtTheShip THEN
   EScore = EScore + hurtTheShip
  END IF

  hurtTheShip = 0

  PRJ.MoveAndDrawProjectiles LLaser(), MAXLLASERS
  PRJ.MoveAndDrawProjectiles Missile(), MAXMISSILES
  PRJ.MoveAndDrawProjectiles Laser(), MAXLASERS
  PRJ.MoveAndDrawProjectiles CBomb(), MAXCBOMBS
  PRJ.MoveAndDrawProjectiles CMiniBomb(), MAXCMINIBOMBS
  PRJ.MoveAndDrawProjectiles Beam(), MAXBEAMS
  PRJ.MoveAndDrawProjectiles Mine(), MAXMINES
  PRJ.MoveAndDrawProjectiles Mini(), MAXMINIS
  PRJ.MoveAndDrawProjectiles Rml5K(), MAXRML5K
  PRJ.MoveAndDrawProjectiles Rml5KMini(), MAXRMLMINIS

  HandleRML5K

  PRJ.MoveAndDrawProjectiles EnemyProjs(), MAXENEMYPROJS

  Dist& = 0
  FOR I = 1 TO MAXENEMYS
   IF Enemys(I).Used THEN
    TempDist& = SQR((MyShip.X - Enemys(I).Object.X) * (MyShip.X - Enemys(I).Object.X) + (MyShip.Y - Enemys(I).Object.Y) * (MyShip.Y - Enemys(I).Object.Y)) + Enemys(I).Object.Radius * 2 * Enemys(I).Object.Scale
    IF TempDist& > Dist& THEN Dist& = TempDist&
    PRJ.CheckCollide LLaser(), Enemys(I).Object, MAXLLASERS, Dx, DY, cllas
    PRJ.CheckCollide Missile(), Enemys(I).Object, MAXMISSILES, Dx, DY, cm
    PRJ.CheckCollide Laser(), Enemys(I).Object, MAXLASERS, Dx, DY, cml
    PRJ.CheckCollide CBomb(), Enemys(I).Object, MAXCBOMBS, Dx, DY, cbm
    PRJ.CheckCollide CMiniBomb(), Enemys(I).Object, MAXCMINIBOMBS, Dx, DY, cmbm
    PRJ.CheckCollide Beam(), Enemys(I).Object, MAXBEAMS, Dx, DY, cbam
    PRJ.CheckCollide Mine(), Enemys(I).Object, MAXMINES, Dx, DY, cmin
    PRJ.CheckCollide Mini(), Enemys(I).Object, MAXMINIS, Dx, DY, cmii
    PRJ.CheckCollide Rml5K(), Enemys(I).Object, MAXRML5K, Dx, DY, cmrm
    PRJ.CheckCollide Rml5KMini(), Enemys(I).Object, MAXRMLMINIS, Dx, DY, cmrmn

    IF Status = 0 THEN sm = O2D.Collide(MyShip, Enemys(I).Object, sx, sy) ELSE sm = 0

    IF cml AND Enemys(I).NoFreze = 0 THEN
     PRT.CircleExp Dx, DY, 9, 2, 0
     Enemys(I).Ft = TIMER
     Laser(cml).Active = 0
    END IF

    IF TIMER - Enemys(I).Ft > 5 THEN Enemys(I).Ft = 0

    IF sm OR cm OR cbm OR cmbm OR cbam OR cmin OR cmii OR cmrm OR cmrmn OR cllas THEN
     IF cllas THEN LLaser(cllas).Active = 0: SubT = 1
     IF cm THEN Missile(cm).Active = 0: SubT = 3
     IF cbm THEN CBomb(cbm).Active = 0: HandleCBExp cbm, Dx, DY: SubT = 10
     IF cbam THEN SubT = 1
     IF cmbm THEN CMiniBomb(cmbm).Active = 0: SubT = 3
     IF cmin THEN Mine(cmin).Active = 0: SubT = 3
     IF cmii THEN Mini(cmii).Active = 0: SubT = 6
     IF cmrm THEN PRT.CircleExp INT(Rml5K(cmrm).Object.X), INT(Rml5K(cmrm).Object.Y), 20, 2, 0: Rml5K(cmrm).Active = 0: SubT = 10
     IF cmrmn THEN Rml5KMini(cmrmn).Active = 0: SubT = 6
     IF sm THEN SubT = Enemys(I).MHp: Dx = sx: DY = sy

     DS4QB.PlaySoundEx 2, CURRENT, CURRENT, CURRENT, CURRENT
     PRT.CircleExp Dx, DY, 13, 2, 0

     oh = Enemys(I).Hp
     Enemys(I).Hp = Enemys(I).Hp - SubT
     IF Enemys(I).Hp <= 0 THEN Enemys(I).Hp = 0: IF INT(RND * 50) + 1 = 25 AND (NOT sm) THEN PWRUP.AddPowerUp 8, INT(Enemys(I).Object.X), INT(Enemys(I).Object.Y)

     IF NOT sm THEN
       Score = Score + (Enemys(I).Score / Enemys(I).MHp) * (oh - Enemys(I).Hp)
      ELSE
       EScore = EScore + (oh - Enemys(I).Hp)
     END IF
    END IF
  
   END IF
 
   ENMY.DoAi I
  NEXT I

  ZoomF! = ZoomF! - (((.75 / 320) * Dist&) / 10)
  
  FOR I = 1 TO MAXPOWERUPS
   PWRUP.MoveAndDraw I
   IF PowerUps(I).Used AND Status = 0 THEN
    IF O2D.RadiusCollide(MyShip, PowerUps(I).Object) THEN
     IF PowerUps(I).WeaponN THEN
       HaveWeapon(PowerUps(I).WeaponN) = HaveWeapon(PowerUps(I).WeaponN) + PowerUps(I).Ammo
      ELSE
       Lives = Lives + PowerUps(I).Ammo
     END IF
     PowerUps(I).Used = 0
    END IF
   END IF
  NEXT I

  PRJ.CheckCollide EnemyProjs(), MyShip, MAXENEMYPROJS, Dx, DY, J
 
  IF J AND Status = 0 THEN
   DS4QB.PlaySoundEx 2, CURRENT, CURRENT, CURRENT, CURRENT
   PRT.CircleExp Dx, DY, 10, 2, 0
   EScore = EScore + EnemyProjs(J).Damage
   EnemyProjs(J).Active = 0
  END IF

  IF EScore > ScoreLose THEN EScore = ScoreLose

  PRT.MoveAndDrawParticles

  IF Status = 3 THEN
   IF blah2# = 0 THEN blah2# = TIMER
   MyShip.Speed = MyShip.Speed + (-MyShip.Speed / 10)
   IF (INT(TIMER - blah2#) AND 1) = 0 THEN Text.Colour = 32: Text.y = 96: TX.CPrint "Required score not reached."
   IF blah2# AND (TIMER - blah2#) >= 7 THEN rCode = -4: EXIT DO
  END IF

  SetCam (MyShip.X), (MyShip.Y), ZoomF!
  
  GOSUB DrawBars
 
  CSPcopy EMS.Layer, &HA000
 LOOP UNTIL XKey(&H1)

 IF XKey(&H1) THEN rCode = -2

 DeinitKbd

 CSClear EMS.Layer, 0

 PRT.ClearAllParts

 FOR I = 1 TO MAXENEMYS
  Enemys(I).Used = 0
 NEXT I

 PlayLevel = rCode

 EXIT FUNCTION

DrawBars:

 ' // Score bar thingo --- START ---

 DEF SEG = EMS.Layer

 barSz = 94
 barScale# = barSz / ABS(ScoreWin)

 nSize = barScale# * ABS(ScoreWin * ScoreWinNeed)
 OScore = OScore + 1
 IF OScore > INT(Score) THEN OScore = INT(Score)
 bSize = OScore * barScale#
 IF bSize > barSz THEN bSize = barSz
 FOR I = 1 TO barSz
  C = (I / barSz) * 16
  IF I > bSize THEN C = 0
  IF C THEN BBoxF64 EMS.Layer, 0, 51 + (barSz - I), 15, 51 + (barSz - I) + 1, C
 NEXT I

 barScale# = barSz / ABS(ScoreLose)
 OEScore = OEScore + .1
 IF OEScore > EScore THEN OEScore = EScore
 bSize = OEScore * barScale#
 IF bSize > barSz THEN bSize = barSz
 FOR I = 1 TO barSz
  C = ((I / barSz) * 32) + 128
  IF I > bSize OR C = 8 THEN C = 0
  IF C THEN BBoxF64 EMS.Layer, 305, 51 + (barSz - I), 319, 51 + (barSz - I), C
 NEXT I
 
 ' // Score bar thingo --- END ---
 ' // Ammo bar thingo --- START ---

 Text.Colour = 255
 IF DiffLev > 1 THEN TX.Locate 24: TX.CPrint STR$(Lives) + " lives."
 IF HaveWeapon(CurrentWeapon) THEN
  IF HaveWeapon(CurrentWeapon) > 0 THEN G$ = STR$(HaveWeapon(CurrentWeapon)) + " ammo."
  IF HaveWeapon(CurrentWeapon) = -1 THEN G$ = " infinite ammo."
  TX.Locate 25: TX.CPrint wepHave(CurrentWeapon) + " :" + G$
 END IF

 FOR I = 1 TO 8
  fx = (11 + (I * 2)) * 8 - 8
  cc = 255
  IF CurrentWeapon = I THEN cc = 32
  IF HaveWeapon(I) = 0 THEN cc = 220
  CSPrint EMS.Layer, fx, 0, LTRIM$(RTRIM$(STR$(I))), cc
  cc = 255
 NEXT I

 DrawHUD

 ' // Ammo bar thingo --- END ---

RETURN

END FUNCTION

SUB PWRUP.AddPowerUp (Index, X, Y)
 FOR I = 1 TO MAXPOWERUPS
  IF PowerUps(I).Used = 0 THEN
   PowerUps(I) = PowerUpTemplate(Index)
   PowerUps(I).Object.Colour = 32
   PowerUps(I).Object.Scale = .25
   PowerUps(I).Object.X = X
   PowerUps(I).Object.Y = Y
   PowerUps(I).Used = -1
   EXIT SUB
  END IF
 NEXT I
END SUB

SUB PWRUP.ClearPowerUps
 FOR I = 1 TO MAXPOWERUPS
  PowerUps(I).Used = 0
 NEXT I
END SUB

SUB PWRUP.MoveAndDraw (I)
 IF PowerUps(I).Used THEN
  OldX = PowerUps(I).Object.X: OldY = PowerUps(I).Object.Y
 
  PowerUps(I).Object.Ang = PowerUps(I).Object.Ang + 1
  PowerUps(I).Object.AngOff = PowerUps(I).Object.AngOff + 12
  O2D.Check PowerUps(I).Object
  O2D.Propell PowerUps(I).Object, 1.2

  IF PowerUps(I).Object.X - (PowerUps(I).Object.Radius * PowerUps(I).Object.Scale) > 320 THEN PowerUps(I).Used = 0
  IF PowerUps(I).Object.Y - (PowerUps(I).Object.Radius * PowerUps(I).Object.Scale) > 200 THEN PowerUps(I).Used = 0
  IF PowerUps(I).Object.X + (PowerUps(I).Object.Radius * PowerUps(I).Object.Scale) < 0 THEN PowerUps(I).Used = 0
  IF PowerUps(I).Object.Y + (PowerUps(I).Object.Radius * PowerUps(I).Object.Scale) < 0 THEN PowerUps(I).Used = 0

  A = ((PowerUps(I).Object.Ang + 180 + 720) MOD 360)
  NewX = PowerUps(I).Object.X + (PowerUps(I).Object.X - OldX) + ((PowerUps(I).Object.Radius * PowerUps(I).Object.Scale) * Cosine(A))
  NewY = PowerUps(I).Object.Y + (PowerUps(I).Object.Y - OldY) + ((PowerUps(I).Object.Radius * PowerUps(I).Object.Scale) * Sine(A))
  R = RND
  R = R - (R / 2)
  PRT.AddPart INT(NewX), INT(NewY), -((PowerUps(I).Object.X - OldX) / 10) + R, -((PowerUps(I).Object.Y - OldY) / 10) + R, 1, 6, 0, Red, 0

  O2D.Draw PowerUps(I).Object
 END IF
END SUB

