Attribute VB_Name = "modMain"
'-------------------------------------------------------------------------------------
'
'  Project: Shooter
'  Date:    24/04/03
'  File:    modMain
'
'  Description
'   The Main loop of the program exists here along with various branching calls
'-------------------------------------------------------------------------------------
Option Explicit
Sub doMain()
    
    Do
        nCounter = nCounter + 1
        Call DD_DrawAll
        'This flips everything to the Primary Surface
        Call PrimBuf.Flip(Nothing, DDFLIP_WAIT)
        'Process Enemy/Button/Collision and So Forth...
        If bPause = False Then
            Call DoMovement
            Call DoCollisions
        End If
        
        IncreaseScore
        
        Keyboard.GetDeviceStateKeyboard KeyboardState
        'Make sure mouse remains hidden
        Call MouseRefresh
        
        'Key Check
        CheckKeyboard
        
        'This is so windows can process other events
        DoEvents

    'This tells the program to loop until the user quits the program
    Loop Until Running = False

End Sub

Sub GameInit()
    Dim nLoop   As Long
    
    Randomize Timer
    
    nScreen = SCREEN_MENU
    nMenuPos = 400
    nMenu = MENU_DELAY
    For nLoop = 1 To 10
        nHighScore(nLoop) = 1000 * (11 - nLoop)
        sHighScore(nLoop) = "Scottie Dog"
    Next nLoop
    
    
    Call SetUpGraphics(True)
    
End Sub

Sub NewGameInit()

    Dim nLoop   As Long
    
    PX = 400
    PY = 600
    PStartY = 120
    PAni = 0
    
    nScore = 0
    
    Call LoadMap

    PWeap = 1  'Strength of the weapon
    PDual = False
    PSide = False
    PBack = False
    PSpeed = 2
    PHealth = 80
    PLives = 3
    AutoFireSpeed = 25  '1/2 a second?
    BigFireSpeed = 50   '1 a second
    yTextDir = 1
    MapPointer = (MAXMAP / 2) - 10
    MapScroll = 0
    bMapScroll = True
    bDontDrawTop = False
    bDontDrawBottom = False

    'Set up an enemy group
    With EnemyGroups(1)
        .Number = 3
        .Alive = 3
        .Bonus = 0
        .Gem = Int(Rnd(1) * 4)
        
        .Counter(1) = 8
        .Frame(1) = ENEMY_SMLROCK1
        .Hits(1) = 2
        .State(1) = 1
        .Score(1) = 100
        .nType(1) = 3
        .xPos(1) = 350
        .yPos(1) = -50
        
        .Counter(2) = 8
        .Frame(2) = ENEMY_SMLROCK2
        .Hits(2) = 2
        .State(2) = 1
        .Score(2) = 100
        .nType(2) = 1
        .xPos(2) = 250
        .yPos(2) = -40
        
        .Counter(3) = 8
        .Frame(3) = ENEMY_SMLROCK3
        .Hits(3) = 2
        .State(3) = 1
        .Score(3) = 100
        .nType(3) = 2
        .xPos(3) = 450
        .yPos(3) = -20
    End With
    EnemyGroups(2) = EnemyGroups(1)
    EnemyGroups(3) = EnemyGroups(1)
    EnemyGroups(4) = EnemyGroups(1)
    EnemyGroups(2).xPos(1) = 300
    EnemyGroups(2).xPos(2) = 200
    EnemyGroups(2).xPos(3) = 500
    EnemyGroups(5) = EnemyGroups(2)
    EnemyGroups(6) = EnemyGroups(2)
    EnemyGroups(7) = EnemyGroups(2)
    EnemyGroups(7).xPos(1) = -10
    EnemyGroups(7).xPos(2) = 0
    EnemyGroups(7).xPos(3) = 10
    EnemyGroups(7).yPos(1) = -10
    EnemyGroups(7).yPos(2) = -10
    EnemyGroups(7).yPos(3) = -10
    EnemyGroups(8) = EnemyGroups(2)
    With EnemyGroups(8)
        .Number = 4
        .Alive = 4
        .Bonus = 200
        .Gem = Int(Rnd(1) * 4)
        .xPos(1) = -10
        .xPos(2) = -10
        .xPos(3) = 10
        .yPos(1) = -10
        .yPos(2) = -10
        .yPos(3) = 10
        .Counter(3) = 8
        .Frame(4) = ENEMY_MIDROCK1
        .Hits(4) = 4
        .State(4) = 1
        .Score(4) = 100
        .nType(4) = 9
        .xPos(4) = 0
        .yPos(4) = -40
    End With
    EnemyGroups(9) = EnemyGroups(8)
'    Call LoadEnemyData
    


    With Enemies(1)
        .Counter = 8
        .Frame = ENEMY_UFO
        .Hits = 3
        .State = 2
        .Score = 150
        .Type = 4
        .xPos = 600
        .yPos = -70
        .Speed = 1
    End With
    With Enemies(2)
        .Counter = 8
        .Frame = ENEMY_UFO
        .Hits = 3
        .State = 2
        .Score = 150
        .Type = 4
        .xPos = 600
        .yPos = -60
        .xDest = 60
        .Speed = 1
    End With
    With Enemies(3)
        .Counter = 8
        .Frame = ENEMY_UFO
        .Hits = 3
        .State = 2
        .Score = 150
        .Type = 4
        .xPos = 600
        .yPos = -50
        .xDest = 120
        .Speed = 1
        .ShootDelay = ONESECOND
    End With
    With Enemies(4)
        .Counter = 8
        .Frame = ENEMY_UFO
        .Hits = 3
        .State = 2
        .Score = 150
        .Type = 4
        .xPos = 600
        .yPos = -40
        .xDest = 180
        .Speed = 1
    End With
    With Enemies(5)
        .Counter = 10
        .Frame = ENEMY_MIDROCK1
        .Hits = 20
        .State = 2
        .Score = 200
        .Type = 5
        .xPos = 450
        .yPos = -64
    End With
    With Enemies(6)
        .Counter = 10
        .Frame = ENEMY_MIDROCK1 + 3
        .Hits = 20
        .State = 2
        .Score = 200
        .Type = 5
        .xPos = 370
        .yPos = -70
    End With
    With Enemies(7)
        .Counter = 10
        .Frame = ENEMY_MIDROCK1 + 6
        .Hits = 20
        .State = 2
        .Score = 200
        .Type = 5
        .xPos = 320
        .yPos = -90
        .Spawns = 7
    End With
    With Enemies(8)
        .Counter = 10
        .Frame = ENEMY_BIGROCK1
        .Hits = 25
        .State = 2
        .Score = 200
        .Type = 6
        .xPos = 220
        .yPos = 100
        .Spawns = 8
        
    End With
    With Enemies(9)
        .Counter = 10
        .Frame = ENEMY_BIGROCK2
        .Hits = 25
        .State = 2
        .Score = 200
        .Type = 6
        .xPos = 500
        .yPos = 100
        .Spawns = 9
    End With
    With Enemies(10)
        .Counter = 8
        .Frame = ENEMY_DRONE
        .Hits = 3
        .State = 2
        .Score = 150
        .Type = 4
        .xPos = 500
        .yPos = -60
        .xDest = 60
        .Speed = 1
    End With
    
'PowerUp Table
    With PowerUps(1)
        .Active = False
        .Available = True
        .Collected = 0
        .Needed = 5
        .Type = PUP_AUTOFIRE
        .Next = 2
    End With
    With PowerUps(2)
        .Active = False
        .Available = False
        .Collected = 0
        .Needed = 8
        .Type = PUP_AUTOFIRE
        .Next = 0
    End With
    With PowerUps(3)
        .Active = False
        .Available = True
        .Collected = 0
        .Needed = 6
        .Type = PUP_POWER
        .Next = 0
    End With
    With PowerUps(4)
        .Active = False
        .Available = True
        .Collected = 0
        .Needed = 2
        .Type = PUP_DUALFIRE
        .Next = 0
    End With
    PowerUps(0).Collected = 4

'Clear out the arrays for gems, stars, and missiles
    For nLoop = 1 To MAXSTARS
        Stars(nLoop).Active = False
    Next nLoop
    For nLoop = 1 To MAXGEMS
        Gems(nLoop).Type = 0
    Next nLoop
    For nLoop = 1 To MAXMISSILES
        Missiles(nLoop).Type = 0
    Next nLoop
    
End Sub
Sub SetUpGraphics(Optional bCreate As Boolean)
'Set Up the Graphic Offsets for everything.
'Comes from the file gOffset.dat
'if bCreate is true will hardcode the data in and save the file out...
    Dim nLoop   As Long

    If bCreate Then
    
        'Graphic Offsets...
        POffset(P_OFF_SHIP, 1) = 16         'Main Ship Graphic
        POffset(P_OFF_SHIP, 2) = 9
        POffset(P_OFF_SHIP - 1, 1) = 20     'Ship moving left
        POffset(P_OFF_SHIP - 1, 2) = 9
        POffset(P_OFF_SHIP + 1, 1) = 20     'Ship moving right
        POffset(P_OFF_SHIP + 1, 2) = 9
        POffset(P_OFF_WEAP1, 1) = 27        'Small Gun
        POffset(P_OFF_WEAP1, 2) = 0
        POffset(P_OFF_THRUST_LEFT, 1) = 21  'Left Thruster...
        POffset(P_OFF_THRUST_LEFT, 2) = 12
        POffset(P_OFF_THRUST_RIGHT, 1) = 37 'Right Thruster...
        POffset(P_OFF_THRUST_RIGHT, 2) = 12
        POffset(P_OFF_WEAP2, 1) = 24         'Dual Shot
        POffset(P_OFF_WEAP2, 2) = -2
        
        'Explosion Offsets...
        For nLoop = 0 To 7
            With ExpDetail(nLoop + 1)
                .OffsetX = 16
                .OffsetY = 16
                .StartX = nLoop * 32
                .StartY = 0
                .Height = 32
                .Width = .StartX + 32
                .Next = nLoop + 2
                .Delay = EXPLOSIONSPEED
            End With
        Next nLoop
        ExpDetail(8).Next = 0
        With ExpDetail(1)
            .Width = 8
            .Height = 10
            .OffsetX = 3
            .OffsetY = 4
        End With
        With ExpDetail(2)
            .StartX = 32
            .Width = 45
            .Height = 12
            .OffsetX = 7
            .OffsetY = 6
        End With
        With ExpDetail(3)
            .StartX = 64
            .Width = 82
            .Height = 16
            .OffsetX = 10
            .OffsetY = 8
        End With
        With ExpDetail(4)
            .StartX = 96
            .Width = 117
            .Height = 22
            .OffsetX = 12
            .OffsetY = 12
        End With
        With ExpDetail(5)
            .StartX = 128
            .Width = 155
            .Height = 27
            .OffsetX = 15
            .OffsetY = 14
        End With
        For nLoop = 0 To 7
            With ExpDetail(nLoop + 9)
                .OffsetX = 7
                .OffsetY = 7
                .StartX = nLoop * 64
                .StartY = 32
                .Height = .StartY + 64
                .Width = .StartX + 64
                .Next = nLoop + 10
                .Delay = EXPLOSIONSPEED + 1
            End With
            ExpDetail(16).Next = 0
            ExpDetail(10).OffsetX = 13
            ExpDetail(10).OffsetY = 14
            ExpDetail(11).OffsetX = 17
            ExpDetail(11).OffsetY = 19
            ExpDetail(12).OffsetX = 24
            ExpDetail(12).OffsetY = 24
            ExpDetail(13).OffsetX = 30
            ExpDetail(13).OffsetY = 29
            ExpDetail(14).OffsetX = 31
            ExpDetail(14).OffsetY = 32
            ExpDetail(15).OffsetX = 31
            ExpDetail(15).OffsetY = 31
            ExpDetail(16).OffsetX = 33
            ExpDetail(16).OffsetY = 33
        Next nLoop
        For nLoop = 0 To 8
            With ExpDetail(nLoop + 17)
                .OffsetX = 7
                .OffsetY = 7
                .StartX = nLoop * 64
                .StartY = 96
                .Height = .StartY + 64
                .Width = .StartX + 64
                .Next = nLoop + 18
                .Delay = EXPLOSIONSPEED + 5
            End With
            ExpDetail(25).Next = 0
        Next nLoop
        
        'Load in the GEM graphics
        For nLoop = 1 To 8
            With GemDetail(nLoop)
                .Surface = 16
                .OffsetX = 5
                .OffsetY = 6
                .StartX = nLoop * 16 + (2 * 16)
                .StartY = 0
                .Height = .StartY + 16
                .Width = .StartX + 16
                .Next = nLoop + 1
                .Delay = 6
            End With
            GemDetail(8).Next = 1
            GemDetail(2).OffsetX = 4
            GemDetail(3).OffsetX = 3
            GemDetail(4).OffsetX = 1
            GemDetail(5).OffsetX = 1
            GemDetail(6).OffsetX = 1
            GemDetail(7).OffsetX = 3
            GemDetail(8).OffsetX = 4
        Next nLoop
    '    Call CreateGem(400, 200, 1)
        
        LoadEnemyData
        
    End If  'End of bCreate
    
End Sub

Sub LoadEnemyData()
'Set up the enemy Sprite Data
    Dim nLoop   As Long
    Dim mLoop   As Long
    
    'Enemy Offsets...
    For nLoop = 0 To 15
        With EnemyDetail(nLoop + 1)
            .Surface = 32
            .OffsetX = 16
            .OffsetY = 16
            .StartX = nLoop * 32 + (4 * 32)
            .StartY = 0
            .Height = .StartY + 32
            .Width = .StartX + 32
            .Next = nLoop + 2
            .Delay = 6
        End With
        With EnemyDetail(nLoop + 17)
            .Surface = 32
            .OffsetX = 16
            .OffsetY = 16
            .StartX = nLoop * 32
            .StartY = 32
            .Height = .StartY + 32
            .Width = .StartX + 32
            .Next = nLoop + 18
            .Delay = 6
        End With
        With EnemyDetail(nLoop + 33)
            .Surface = 32
            .OffsetX = 16
            .OffsetY = 16
            If nLoop > 3 Then
                .StartX = nLoop * 32 - (4 * 32)
                .StartY = 64
            Else
                .StartX = nLoop * 32 + (16 * 32)
                .StartY = 32
            End If
            .Height = .StartY + 32
            .Width = .StartX + 32
            .Next = nLoop + 34
            .Delay = 6
        End With
        With EnemyDetail(nLoop + 49)
            .Surface = 32
            .OffsetX = 16
            .OffsetY = 16
            If nLoop < 8 Then
                .StartX = nLoop * 32 + (12 * 32)
                .StartY = 64
            Else
                .StartX = nLoop * 32 - (8 * 32)
                .StartY = 96
            End If
            .Height = .StartY + 32
            .Width = .StartX + 32
            .Next = nLoop + 50
            .Delay = 6
        End With
        With EnemyDetail(nLoop + 65)
            .Surface = 32
            .OffsetX = 16
            .OffsetY = 16
            If nLoop < 2 Then
                .StartX = nLoop * 32 + (18 * 32)
                .StartY = 96
            Else
                .StartX = nLoop * 32 - (2 * 32)
                .StartY = 128
            End If
            .Height = .StartY + 32
            .Width = .StartX + 32
            .Next = nLoop + 66
            .Delay = 6
        End With
    Next nLoop
    EnemyDetail(16).Next = 1
    EnemyDetail(32).Next = 17
    EnemyDetail(48).Next = 33
    EnemyDetail(64).Next = 49
    EnemyDetail(80).Next = 65
    
    '64x64 Rocks
    For nLoop = ENEMYGRAPH_64 To ENEMYGRAPH_64 + 22
        With EnemyDetail(nLoop)
            .Surface = 64
            .OffsetX = 32
            .OffsetY = 32
            
            .StartX = (nLoop - 85) * 64
            .StartY = 128
            If nLoop < 85 Then
                .StartX = (nLoop - 75) * 64
                .StartY = 64
            End If
            If nLoop < 75 Then
                .StartX = (nLoop - 65) * 64
                .StartY = 0
            End If
            
            .Height = .StartY + 64
            .Width = .StartX + 64
            .Next = nLoop + 1
            .Delay = 8
        End With
    Next nLoop
    EnemyDetail(87).Next = ENEMYGRAPH_64
    
    '128x128 Rocks
    For mLoop = 0 To 4
        For nLoop = 0 To 4
        With EnemyDetail(ENEMYGRAPH_128 + nLoop + (mLoop * 5))
            .Surface = 128
            .OffsetX = 48
            .OffsetY = 48
            .StartX = nLoop * 128
            .StartY = 128 + (mLoop * 128)
            .Height = .StartY + 96
            .Width = .StartX + 96
            .Next = ENEMYGRAPH_128 + 1 + nLoop + (mLoop * 5)
            .Delay = 16
        End With
        With EnemyDetail(ENEMYGRAPH_128 + nLoop + (mLoop * 5) + 25)
            .Surface = 128
            .OffsetX = 48
            .OffsetY = 48
            .StartX = nLoop * 128
            .StartY = 768 + (mLoop * 128)
            .Height = .StartY + 96
            .Width = .StartX + 96
            .Next = ENEMYGRAPH_128 + 1 + nLoop + (mLoop * 5) + 25
            .Delay = 16
        End With
        Next nLoop
    Next mLoop
    EnemyDetail(112).Next = ENEMYGRAPH_128
    EnemyDetail(137).Next = ENEMYGRAPH_128 + 25
End Sub
Sub CheckKeyboard()

    Select Case nScreen
        Case SCREEN_GAME
            KeyboardGame
        Case SCREEN_MENU
            KeyboardMenu
        Case SCREEN_HIGH
            KeyboardHigh
    End Select
End Sub
Sub KeyboardGame()

    Dim bCanDo  As Boolean
    
'A whole butch of things prevent you from doing much (except pause/unpause)
    bCanDo = True
    If bPause = True Then bCanDo = False
    If PAni > 0 Then bCanDo = False
    
'Check the keyboard
    If bCanDo Then
    'Game is in swing...
        If KeyboardState.Key(DIK_UP) Then
            PY = PY - PSpeed
            If PY < 50 Then PY = 50
        End If
        If KeyboardState.Key(DIK_DOWN) Then
            PY = PY + PSpeed
            If PY > 560 Then PY = 560
            PThruster = True
        Else
            PThruster = False
        End If
        PMove = 0
        If KeyboardState.Key(DIK_LEFT) Then
            PX = PX - PSpeed
            ShakeX = 2
            If PX < 48 Then PX = 48
            PMove = -P_SHIP_GRAPHIC
        End If
        If KeyboardState.Key(DIK_RIGHT) Then
            PX = PX + PSpeed
            ShakeX = -2
            If PX > 752 Then PX = 752
            PMove = P_SHIP_GRAPHIC
        End If
        If KeyboardState.Key(DIK_LCONTROL) Then
            If kbFirePressed = 0 Then
                Call CreateMissile
                kbFirePressed = AutoFireSpeed
            End If
        Else
            kbFirePressed = 0
        End If
        If KeyboardState.Key(DIK_LSHIFT) Then
        'Big Guns...
            kbBigGun = BigFireSpeed
        End If
        'The Alt key swaps through the power ups available
        If KeyboardState.Key(DIK_LMENU) Then
            If kbChangePower = 0 And pup_upgrade = False Then
                Call ChangePowerUp
                kbChangePower = KEY_DELAY
            End If
        End If
    End If  'end of pause
        
    If KeyboardState.Key(DIK_SPACE) Then
        If bPause = True Then
            bPause = False
        Else
            bPause = True
        End If
    End If
    'Check if the escape key has been pressed and exit if it has
    If KeyboardState.Key(DIK_ESCAPE) Then
        Running = False
    End If

'If the player is dead we still need to check the fire key...
    If KeyboardState.Key(DIK_LCONTROL) Then
        If kbFirePressed = 0 Then
            If PLives = 0 Then
                bInit = True
                If SortHighScores Then
                    nScreen = SCREEN_HIGH
                Else
                    nScreen = SCREEN_MENU
                End If
            End If
            kbFirePressed = AutoFireSpeed
        End If
    End If

    'Process all keyboard ticks here...
    If kbFirePressed > 0 Then kbFirePressed = kbFirePressed - 1
    If kbChangePower > 0 Then kbChangePower = kbChangePower - 1
End Sub
Sub KeyboardMenu()
    'Check if the escape key has been pressed and exit if it has
    If KeyboardState.Key(DIK_ESCAPE) Then
        Running = False
    End If
    If KeyboardState.Key(DIK_LCONTROL) Then
        If kbFirePressed = 0 Then
            nScreen = SCREEN_GAME
            bInit = True
            kbFirePressed = AutoFireSpeed
        End If
    End If
    If kbFirePressed > 0 Then kbFirePressed = kbFirePressed - 1
End Sub
Sub KeyboardHigh()
    'Check if the escape key has been pressed and exit if it has
    If KeyboardState.Key(DIK_ESCAPE) Then
        Running = False
    End If
    If KeyboardState.Key(DIK_LCONTROL) Then
        If kbFirePressed = 0 Then
            nScreen = SCREEN_MENU
            bInit = True
            kbFirePressed = AutoFireSpeed
        End If
    End If
    If kbFirePressed > 0 Then kbFirePressed = kbFirePressed - 1
End Sub
Sub LoadMap(Optional bSave As Boolean)
'if bSave is True the the map is generated at random and saved out
'Everything is then loaded anyway

    Dim lenpos As Long
    Dim xPos    As Long
    Dim yPos    As Long
    Dim nTemp   As Long
    
    lenpos = LenB(Map(0, 0))
    If bSave Then
        Open App.Path & "\Data\Map01.dat" For Output As #1 'For Random As #1
        For yPos = 0 To 200
            For xPos = 0 To 11
                Map2(xPos, yPos) = 0
                If yPos <= 100 Then Map(xPos, yPos) = Int(Rnd(1) * 5) + 4
            Next xPos
        Next yPos
        
        For yPos = 0 To 200 Step 3
            Map2(0, yPos) = 10
            Map2(0, yPos + 1) = 11
            Map2(1, yPos + 1) = 12
            Map2(0, yPos + 2) = 13
        Next yPos
        For yPos = 0 To 196 Step 4
            Map2(10, yPos) = 20
            Map2(9, yPos + 1) = 21
            Map2(10, yPos + 1) = 22
            Map2(9, yPos + 2) = 23
            Map2(10, yPos + 2) = 24
            Map2(9, yPos + 3) = 25
            Map2(10, yPos + 3) = 26
        Next yPos
        
        nTemp = 1
        For yPos = 0 To MAXMAP / 2
            For xPos = 0 To 11
                Print #1, Map(xPos, yPos);
            Next xPos
            Print #1, ""
        Next yPos
        
        For yPos = 0 To MAXMAP
            For xPos = 0 To 11
                Print #1, Map2(xPos, yPos);
            Next xPos
            Print #1, ""
        Next yPos
        
        For yPos = 0 To 100
            Print #1, MapFlags(yPos);
        Next yPos
        Print #1, ""
                
        'Spawn points come next
            'Set up a spawn point
        Spawn(1).Map = MapPointer - 1
        Spawn(1).Group = 1
        Spawn(2).Map = MapPointer - 1
        Spawn(2).Group = 2
        Spawn(3).Map = MapPointer - 2
        Spawn(3).Group = 3
        Spawn(4).Map = MapPointer - 3
        Spawn(4).Group = 4
        Spawn(4).Map = MapPointer - 3
        Spawn(4).Group = 5
        Spawn(4).Map = MapPointer - 4
        Spawn(4).Group = 6
        
        For yPos = 0 To MAXSPAWNS
            With Spawn(yPos)
                Print #1, .Action, .Group, .Map, .Type, .xDest, .xPos, .yDest, .yPos
            End With
        Next yPos
        Close #1

    End If  'End of bSave
    
    Open App.Path & "\Data\Map01.dat" For Input As #1
    For yPos = 0 To MAXMAP / 2
        For xPos = 0 To 11
            Input #1, Map(xPos, yPos)
        Next xPos
    Next yPos
    For yPos = 0 To MAXMAP
        For xPos = 0 To 11
            Input #1, Map2(xPos, yPos)
        Next xPos
    Next yPos
        
    For yPos = 0 To 100
        Input #1, MapFlags(yPos)
    Next yPos
    
    For yPos = 0 To MAXSPAWNS
        With Spawn(yPos)
            Input #1, .Action, .Group, .Map, .Type, .xDest, .xPos, .yDest, .yPos
        End With
    Next yPos
    
    Close #1
    
End Sub
Sub DamageShip(nAmount As Long)
'This routine is called to damage the ship a little bit...
    If PLives = 0 Then GoTo EndDamageShip
    
    GammaFlashRed
    PHealth = PHealth - nAmount
    If PHealth < 1 Then
        PAni = 60
        Call CreateBigExplosion(PX + Int(Rnd(1) * 32) - 16, PY + Int(Rnd(1) * 32) - 16, True)
        ShakeX = ShakeX + Int(Rnd(1) * 8) - 4
        ShakeY = ShakeY + Int(Rnd(1) * 8) - 4
    End If
    ShakeX = ShakeX + Int(Rnd(1) * nAmount) - (nAmount / 2)
    ShakeY = ShakeY + Int(Rnd(1) * nAmount) - (nAmount / 2)
EndDamageShip:
End Sub
Sub DamageEnemy(nEnemy As Long, nDamage As Long)
'This will damage an enemy - hopefully terminally
    With Enemies(nEnemy)
        .Flash = True       'We've been hit so make it flash
        .FlashCounter = FLASH_DELAY
        .Hits = .Hits - nDamage
        If .Hits < 1 Then
            Call CreateBigExplosion(.xPos, .yPos, False)
            Call CreateGem(.xPos, .yPos, 1, 1)
            nScore = nScore + .Score
            If .Group > 0 Then
                EnemyGroups(.Group).Alive = EnemyGroups(.Group).Alive - 1
                If EnemyGroups(.Group).Alive = 0 Then
                    nScore = nScore + EnemyGroups(.Group).Bonus
                    If EnemyGroups(.Group).Gem > 0 Then Call CreateGem(.xPos, .yPos, EnemyGroups(.Group).Gem, 1)
                End If
            End If
            If .Spawns > 0 Then
                Call EnemySpawnGroup(.Spawns, .xPos, .yPos)
                .Spawns = 0
            End If
            .Type = 0   'Finally deactivate this enemy
        End If
    End With
End Sub

Public Function ConvToSignedValue(lngValue As Long) As Integer

    If lngValue <= 32767 Then
        ConvToSignedValue = CInt(lngValue)
    Else
        ConvToSignedValue = CInt(lngValue - 65535)
    End If

End Function

Public Function ConvToUnSignedValue(intValue As Integer) As Long

    If intValue >= 0 Then
        ConvToUnSignedValue = intValue
    Else
        ConvToUnSignedValue = intValue + 65535
    End If

End Function

Sub IncreaseScore()

    If nDispScore < nScore Then
        nDispScore = nDispScore + 1
    End If
    
    If nDispScore < nScore - 500 Then
        nDispScore = nDispScore + 10
    End If
    
    If nDispScore < nScore - 5000 Then
        nDispScore = nDispScore + 100
    End If
    
End Sub
Sub ChangePowerUp()
'The alt key has been pressed so swap to the next power up available
    Dim nLoop   As Long
    Dim nSelect As Long

    
    nSelect = 0
    For nLoop = PowerUps(0).Collected + 1 To MAXPOWERUPS
        If PowerUps(nLoop).Active = False And PowerUps(nLoop).Available Then
            nSelect = nLoop
            nLoop = MAXPOWERUPS
        End If
    Next nLoop
    If nSelect = 0 Then
        For nLoop = 1 To PowerUps(0).Collected
            If PowerUps(nLoop).Active = False And PowerUps(nLoop).Available Then
                nSelect = nLoop
                nLoop = PowerUps(0).Collected
            End If
        Next nLoop
    End If
    PowerUps(0).Collected = nSelect
    
End Sub
Function SortHighScores() As Boolean
    Dim nCount  As Long
    Dim nLoop   As Long

    SortHighScores = False
    nCount = 0
    For nLoop = 1 To 10
        If nHighScore(nLoop) < nScore And nCount = 0 Then
            nCount = nLoop
        End If
    Next nLoop
    If nCount > 0 Then
        For nLoop = 10 To nCount + 1 Step -1
            nHighScore(nLoop) = nHighScore(nLoop - 1)
            sHighScore(nLoop) = sHighScore(nLoop - 1)
        Next nLoop
        nHighScore(nCount) = nScore
        sHighScore(nCount) = "Tester"
        SortHighScores = True
    End If
End Function
