' Compiler: FreeBASIC 

' **********************************************
' Star Cage source code(single file but includes
' a custom AFlib 2 .bi file).
' Compiles in FreeBASIC versions 0.15 and 0.16. 
' As for the future versions, I really can't tell.
' The code is rather commented but since this
' is a source of a finished game and not of
' a game engine, the endless exceptions
' and nitpicks might annoy you. Sorry about
' that but it was unavoidable.
' **********************************************

' GFXlib 2 declarations.
#include "fbgfx.bi"
' AFlib 2 declarations(part of the lib).
#include "customAFLib2.bi"
' FMOD declarations.
#include "fmod.bi"

' Sound/music subs/functions.
DECLARE SUB setSoundVolume
DECLARE SUB playsample (plsnd as integer ptr)
DECLARE SUB playStreamMusic (musc As String)
DECLARE SUB stopStreamMusic ()

DECLARE SUB MoveDrawShips () ' A sub that moves and draws the enemy ships.
DECLARE SUB StarsLayer ()    ' A sub that draws the stars.
' A sub that initiates a projectile on position px!, py!, with type
' ptyp and so on.
DECLARE SUB InitiateProjectile (px!, py!, ptyp, pangle!, pmode, pduration, ppower!)
' A sub that draws and moves projectiles if they are active(initiated).
DECLARE SUB ProjectileLayer ()
' A sub that initiates an explosion.
DECLARE SUB InitiateExplosion (ex!, ey!, etyp, eduration)
DECLARE SUB ExplosionLayer () ' A sub that draws and manages initiated explosions.
DECLARE SUB InitiatePickup (pix!, piy!, pityp) ' A sub that initiated a pickup.
DECLARE SUB PickupLayer () ' A sub that draws and manages active pickups.
DECLARE SUB DrawMiniMap () ' A sub that draws the mini map(s).
DECLARE SUB MainLoop () ' The main game loop(for all game modes and numbers of players).
DECLARE SUB ShipAI (currentship) ' A sub that moves the enemy ships according to their AI type and
                                 ' the position of the target(first or second player's ships).
DECLARE SUB ProjectileAI (currentprojectile) ' A sub that moves the "smart" projectiles(only one homming projectile in this game).
DECLARE SUB MainMenu () ' The main menu loop.
DECLARE SUB NewGameReset () ' A sub that resets the variables for a new game.
DECLARE SUB NewPhase () ' A sub that spawns new enemies in the play field when you kill
                        ' all of them in a previous phase.
DECLARE SUB InitStage () ' A sub that initiates the new stage variables.
DECLARE SUB BreakScreen () ' A sub that splits the screen(the animation).
DECLARE SUB JoinScreen () ' A sub that joins the screen(the animation).
DECLARE SUB PlanetLayer () ' A sub that draws planets on the screen and controls their rotation.
DECLARE SUB UpgradeShipScreen () ' A loop where you upgrade your ship(upgrade ship menu).
DECLARE SUB InitShipCharacteristics (inittypeship) ' A sub that initiates enemy ship's characteristics
                                                   ' according to its type.
DECLARE SUB SpawnVortex () ' A sub that spawns a vortex in the play field when you finish a stage.
DECLARE SUB SpawnShip (shx!, shy!, shtyp, shangle!) ' A sub that spawns an enemy ships in the play field
                                                    ' on the given location(only used in stage 5).
DECLARE SUB DoBigExplosion () ' A sub that spawns extra explosion when you
                              ' destroy the end game boss.
DECLARE SUB EndGame () ' A sub tha draws the end game animation(s).
DECLARE SUB PrintShipStatus (setfade) ' A sub that prints the status of players' ships in 
                                      ' two players mode with a give fade ration.
DECLARE SUB ScoreScreen () ' A sub that draws the end stage scores screen.
DECLARE SUB ChoosePlayers () ' A loop where you choose if you will play in single or two players mode.
DECLARE SUB AddShips () ' A sub that adds new ships in the play field when
                        ' there is less than 4 of them in it(used in head on head mode).
DECLARE SUB InitHeadOnHead () ' A sub that initiates/resets variables for the head on head game mode.
DECLARE SUB OtherShipLayer () ' A sub that draws the other player's ship in the play field(two players mode).
DECLARE SUB Options () ' Options loop.
DECLARE SUB DrawStars (smode) ' A sub that draws the "stars travel" effect(main menu, options, etc.)

DECLARE SUB neoENCpass (Offset AS ANY PTR, Length&, password$) ' String encryption sub.
DECLARE SUB neoENCdepass (Offsett AS ANY PTR, Lengthh&, passsword$) ' String decryption sub.
DECLARE SUB WriteHighScore () ' A sub that checks for the top scores and
                              ' and prompts you to the input name sub if you
                              ' have an enough high score.
DECLARE SUB ReadHighScore () ' A sub that draws the top scores table.
DECLARE SUB InputName () ' A sub that enables you to input a score for
                         ' the top scores table.
DECLARE SUB Story () ' The sub where the story is executed.
DECLARE SUB PreStage5Anim () ' The sub for story animation before stage 5.
DECLARE SUB PlayAgainMenu () ' The sub for the "Play Again?" question that 
                             ' appears when you finish the game.
DECLARE SUB Instructions ()  ' The sub where instructions are placed.
DECLARE SUB InitiateSparkle (spix!, spiy!, sangle!, spityp) ' The sub for sparkle initiation.
DECLARE SUB SparkleLayer () ' The sub where sparkles are managed.
DECLARE SUB Intro ()

const FALSE = 0
const TRUE = 1
const GFX_v = 640
const GFX_h = 480
const PI = 3.14159

' The following constants represent
' the maximum number of projectiles,
' explosions, ships and sparkles
' that can be simultaneously active 
' during the game. They can be increased 
' if a project requires that. 
const numofprojectiles = 100
const numofexplosions = 700
const numofships = 28
const numofsparkles = 90

' MapBorder represents the horizontal
' and vertical size of the game field. 
' Feel free to change it to suit you 
' needs. A non-square play field
' wouldn't make much sense.
const MapBorder = 2400

' Main type used with the player's
' and enemy ships, explosions,
' planets and so on.
TYPE SpriteType
Alive AS INTEGER
RealX AS SINGLE
RealY AS SINGLE
X AS SINGLE
Y AS SINGLE
Speed AS SINGLE
Locked AS INTEGER
Typ AS INTEGER
LifeTime AS INTEGER
Energy AS INTEGER
Sprite AS INTEGER
AIMode AS INTEGER
AISubMode AS INTEGER
Angle AS SINGLE
SColor AS INTEGER
Shield AS SINGLE
MaxShield AS INTEGER
Acceleration AS SINGLE
TurnLevel AS SINGLE
Reload AS INTEGER
CenterX AS INTEGER
CenterY AS INTEGER
WeaponPower AS SINGLE
MaxReverse AS SINGLE
Battery AS SINGLE
MaxBattery AS SINGLE
WeaponLevel AS INTEGER
VortexScale AS SINGLE
StartSprite AS INTEGER
Score AS INTEGER
Shots AS INTEGER
ShipProj AS INTEGER
END TYPE

' Sound related variables.
DIM SHARED FMODStatus AS INTEGER
DIM SHARED PlaySound AS INTEGER
DIM SHARED sample(18) AS INTEGER PTR
DIM SHARED music_handle AS INTEGER PTR


DIM SHARED Ship(numofships) AS SpriteType
DIM SHARED Star(801) AS SpriteType
DIM SHARED Projectile(numofprojectiles) AS SpriteType
DIM SHARED Explosion(numofexplosions) AS SpriteType
DIM SHARED Sparkle(numofsparkles) AS SpriteType
DIM SHARED Planet(8) AS SpriteType
DIM SHARED Pickup(20) AS SpriteType

' Main ship variable and camera
' variables are dimensioned with 2 elements
' since the game features two players
' split screen mode.
' This allows us to manage both players
' with one FOR loop.
DIM SHARED MainShip(2) AS SpriteType
DIM SHARED CamX(2) AS SINGLE 
DIM SHARED CamY(2) AS SINGLE

' Variables used to flag the 
' brightness of various game options 
' in order to highlight the current one.
DIM SHARED optionfade(10) AS INTEGER
DIM SHARED upgradefade(20) AS INTEGER

' Variable used with the score
' input/store routines.
DIM SHARED scores(4) AS SINGLE
DIM SHARED textarray(9) AS STRING
DIM SHARED plscore AS INTEGER

DIM SHARED fpslimit AS INTEGER
DIM SHARED st as DOUBLE
DIM SHARED FullScreen, FPS2

DIM SHARED SFXVolume, MusicVolume, KeyFree
DIM SHARED startminimapx, startminimapy, menupos, ScreenTransition
DIM SHARED Stage, seconds, PlayingAgain, startplayers, scoreflag, Player1OriginalScore
DIM SHARED Frame1, Frame2, Frame3, Frame4, Frame5, Frame6, Frame7
DIM SHARED GameMode, numofplayers, countplayer, GraphicMode
DIM SHARED PhaseNumber, countplayerdeath(2), PhaseDone, countstageend(2), CountStartStage
DIM SHARED MainShipCheckX, MainShipCheckY, pseconds(2)
DIM SHARED MoveShip, movmode, ShipSpeed, radsangle!, currentship
DIM SHARED vorx!, vory!, countproj, ExtraExplosion
DIM SHARED Starttime&, workpage, pal$
DIM SHARED newship, hitship, sshot, FPSCounter
DIM SHARED playerletter(8) AS STRING
DIM SHARED playername AS STRING
DIM SHARED stextline(6) AS STRING
DIM SHARED warningmsg(2) AS INTEGER

' Pointers and variables where the
' graphics will be stored.
DIM SHARED Sprites1 AS ImageType
DIM SHARED Sprites2 AS ImageType
DIM SHARED Sprites3 AS ImageType
DIM SHARED ProjSprite AS ImageType
DIM SHARED ShipSprite AS ImageType
DIM SHARED PlanetSprite AS ImageType
DIM SHARED PickupSprite AS ImageType
DIM SHARED Font1 AS ImageType
DIM SHARED background(5, 77000*2) AS INTEGER
DIM SHARED ScreenBuffer(2) as any ptr
DIM SHARED FullScreenBuffer(3) as any ptr
DIM SHARED MiniMapBuffer(2) as any ptr
DIM SHARED MiscBuffer1(7) as any ptr
DIM SHARED MiscBuffer2(9) as any ptr

'3D space screen related variables
' ---------------------------------------------
TYPE Point3D
        x       AS SINGLE           '3d x coord
        y       AS SINGLE           'ditto
        z       AS SINGLE           'ditto
        zvel    AS SINGLE           'ZVelocity
END TYPE


CONST LENS = 256                    'camera lens(FOV)
CONST XCENTER = 160                 'middle coords of screen 13
CONST YCENTER = 100                 'our center of projection
CONST MAXSTARS = 200                'number of stars
CONST MAXVEL = 2                    'Maximum speed of star

DIM SHARED Stars(MAXSTARS) AS Point3D           'the stars
' ---------------------------------------------

RANDOMIZE TIMER

' Init star positions(for star travel effect).
FOR i = 0 TO UBOUND(Stars)
    Stars(i).x = -60 + INT(RND * 120)           'x
    Stars(i).y = -60 + INT(RND * 120)           'y
    Stars(i).z = INT(RND * 255)                 'z
    Stars(i).zvel = .3 + RND * MAXVEL           'speed of each star
NEXT i

' Open the setup file and load the
' full screen and FMOD active or
' not variables from it.
OPEN "data/setup.dat" FOR INPUT AS #2
INPUT #2, FullScreen
INPUT #2, FMODStatus
CLOSE #2

fpslimit = 33
PlaySound = TRUE
IF FMODStatus = FALSE THEN PlaySound = FALSE

' If the usage of FMOD is enabled init it
' and if all goes well keep the default
' sound status(PlaySound = TRUE, which
' means use the sound routines freely).
IF FMODStatus = TRUE THEN
FSOUND_Init(44100, 16, 0) 
IF FSOUND_Init(44100, 16, 0) = 0 THEN PlaySound = FALSE
END IF

' Load all the samples.
IF PlaySound = TRUE THEN
sample(1)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/laser1.ogg",0,0,0)
sample(2)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/projhit.ogg",0,0,0)
sample(3)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/boom1.ogg",0,0,0)
sample(4)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/laser2.ogg",0,0,0)
sample(5)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/laser3.ogg",0,0,0)
sample(6)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/powerup.ogg",0,0,0)
sample(7)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/laser4.ogg",0,0,0)
sample(8)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/laser5.ogg",0,0,0)
sample(9)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/warp.ogg",0,0,0)
sample(10)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/swoosh.ogg",0,0,0)
sample(11)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/shieldup.ogg",0,0,0)
sample(12)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/upgrade.ogg",0,0,0)
sample(13)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/cashreg.ogg",0,0,0)
sample(14)=FSOUND_SAMPLE_Load(FSOUND_FREE,"Sound/warning.ogg",0,0,0)
END IF

SCREENRES 640, 480, 8, 2, FullScreen
SCREENSET 1, 0
SETMOUSE 50,50,0 ' Hides the mouse cursor.

' Load all the sprites and the game font.
AF2.InitSpr_PP256 Sprites1, "Graphics/main.spr" 
AF2.InitSpr_PP256 Sprites2, "Graphics/misc1.spr" 
AF2.InitSpr_PP256 Sprites3, "Graphics/misc2.spr" 
AF2.InitSpr_PP256 ShipSprite, "Graphics/ships.spr" 
AF2.InitSpr_PP256 ProjSprite, "Graphics/projs.spr" 
AF2.InitSpr_PP256 Font1, "Graphics/charset1.fnt" 
AF2.InitSpr_PP256 PlanetSprite, "Graphics/planets.spr" 
AF2.InitSpr_PP256 PickupSprite, "Graphics/pickups.spr" 

' Allocate memory for all the custom
' buffers.
ScreenBuffer(1)=ImageCreate(580,450) 
ScreenBuffer(2)=ImageCreate(580,450)
FullScreenBuffer(1)=ImageCreate(640,480)
FullScreenBuffer(2)=ImageCreate(640,480)
FullScreenBuffer(3)=ImageCreate(321,241)
MiniMapBuffer(1)=ImageCreate(120,120) 
MiniMapBuffer(2)=ImageCreate(120,120)
FOR cmbuffer = 1 TO 7
MiscBuffer1(cmbuffer)=ImageCreate(100,100) 
NEXT cmbuffer
FOR cmbuffer = 1 TO 9
MiscBuffer2(cmbuffer)=ImageCreate(160,160) 
NEXT cmbuffer

screenset workpage, workpage xor 1

' Capture the needed graphics and
' store it in proper memory
' buffers.
BLOAD "Graphics/STARCAGE.BGR",0
GET (0,0)-(319,239), background(1, 0)
BLOAD "Graphics/UPGRADESCR.BGR",0
GET (0,0)-(319,239), background(5, 0)
GET (1,1)-(74,80), MiscBuffer1(1)
GET (76,1)-(149,80), MiscBuffer1(2)
GET (151,1)-(224,80), MiscBuffer1(3)
GET (226,1)-(299,80), MiscBuffer1(4)
GET (1,82)-(74,161), MiscBuffer1(5)
GET (76,82)-(149,161), MiscBuffer1(6)
BLOAD "Graphics/SCSTORY1.BGR",0
GET (0,4)-(157,102), MiscBuffer2(1)
GET (159,4)-(316,102), MiscBuffer2(2)
GET (0,104)-(157,202), MiscBuffer2(3)
GET (159,104)-(316,202), MiscBuffer2(4)
BLOAD "Graphics/SCSTORY2.BGR",0
GET (0,4)-(157,102), MiscBuffer2(5)
GET (159,4)-(316,102), MiscBuffer2(6)
GET (0,104)-(157,202), MiscBuffer2(7)
CLS
BLOAD "Graphics/ENDGAME.BGR",0
GET (0,0)-(188,112), MiscBuffer2(8)
BLOAD "Graphics/GAMESCRN.BGR",0
GET (0,0)-(319,239), FullScreenBuffer(3)
GET (249,179)-(305,235), MiscBuffer2(9)

AF2.ClearScreen 0

' Init the in-game stars.
FOR istar = 1 TO 400
Star(istar).X = int(rnd * 700) + 1
Star(istar).Y = int(rnd * 700) + 1
Star(istar).SColor = int(rnd * 7) + 166   
NEXT istar
FOR istar = 401 TO 800
Star(istar).X = int(rnd * 1300) + 1
Star(istar).Y = int(rnd * 1300) + 1
Star(istar).SColor = int(rnd * 6) + 165   
NEXT istar

' Some initial game variables.
startminimapx = 587
startminimapy = 428
sshot = 1
SFXVolume = 3
MusicVolume = 3
pal$ = "NORMAL"
GraphicMode = 1

' Init the game's palette.
AF2.InitPP256pal "Graphics/normal.pal" 

Intro ' Load up the intro.
MainMenu ' Call the main menu loop.

SUB MainLoop ()

startmainloop:
stopStreamMusic
playStreamMusic("Sound/battle.mp3")

DO

' Various variables that loop and enable dozen
' of animations inside the game(their speed 
' or progress) among few other things.
Frame2 = (Frame2 MOD 5) + 1
Frame3 = (Frame3 MOD 8) + 1
Frame5 = (Frame5 MOD 3) + 1
Frame6 = (Frame6 MOD 200) + 1
Frame7 = (Frame7 MOD 6) + 1
IF Frame2 = 2 THEN Frame1 = (Frame1 MOD 4) + 1
IF Frame3 = 2 THEN Frame4 = (Frame4 MOD 2) + 1
IF Frame1 = 0 THEN Frame1 = 1
IF Frame4 = 0 THEN Frame4 = 1

FPS = FPS + 1                     ' Used to count FPS.
if StartTime& + 1 < timer then
 FPS2 = FPS
 FPS = 0
 seconds = seconds + 1
 StartTime& = timer
end if

IF PlaySound = TRUE THEN FSOUND_Update

' When a stage starts this variable is above 
' 0 and depletes in every loop until it reaches 0. 
' It's used to display the starting stage 
' text("Sector #num" and similar).
IF CountStartStage > 0 THEN CountStartStage = CountStartStage - 1

' Switch to work page.
screenset workpage, workpage xor 1

' The next FOR loop enables two players split 
' screen mode. In single player mode it can simply 
' be ignored and is not needed to understand
' the code. Just have in mind that then countplayer
' is always 1. If you want to convert the code into
' single player mode only then MainShip(countplayer) 
' should(but is not obligatory) be converted
' to simply MainShip and few IF clauses where the
' single player mode is separated from the two 
' players mode need to be modified.
FOR countplayer = 1 TO numofplayers
    
AF2.ClearScreen 0 ' Clear the screen.

' Paste all the layers.
StarsLayer    ' Draws the stars on the map.
PlanetLayer   ' Draws the planets on the map
              ' and manages their rotation. Since the
              ' vortex is managed in this sub collision
              ' with it is also checked in it(when
              ' it appears).
PickupLayer   ' Sub that draws the pickups on the screen
              ' and checks for collision with players' ships.
MoveDrawShips ' Sub that draws and manages enemy ships(a path
              ' to the enemy ship AI is in that sub).

ProjectileLayer ' Sub that draws and manages projectiles(moves
                ' them and checks for collision).
SparkleLayer

IF numofplayers = 2 THEN OtherShipLayer 
             ' A sub that draws the opposite
             ' ship in two players mode.

ExplosionLayer  ' Sub that draws and manages the explosions.

' Get the graphics from the screen to
' rotate it later. This graphic is grabged from
' the center of 640*480 screen and enough big to
' enable "full rotation" effect in one player mode
' (edges of the captured sprite mustn't be visible
' during rotation).
GET (100,20)-(639-100,479-20), ScreenBuffer(countplayer)

' Reduce the weapon reload variable if it's
' above 0(the player can only shoot when
' it's 0).
IF MainShip(countplayer).Reload > 0 THEN MainShip(countplayer).Reload = MainShip(countplayer).Reload - 1

' If the current(countplayer) ship is not destroyed 
' allow movement and paste it on the screen.
IF MainShip(countplayer).Alive = TRUE THEN

' In game mode 2(head on head) if any of
' the player's dead the alive one
' shouldn't be able to mode.
IF GameMode = 2 THEN
IF countplayer = 1 AND MainShip(2).Alive = FALSE THEN GOTO skipreducespr:
IF countplayer = 2 AND MainShip(1).Alive = FALSE THEN GOTO skipreducespr:
END IF
 
' If left or right arrow key is pressed
' rotate the screen according to the
' angle and flag the proper ship sprite.
' I only used one IF cluase for both
' players(note how I used countplayer
' variable and the OR operator).
' MainShip().TurnLevel variable is 8
' in the begining(slowest turning)
' and can become 6 or 4 later with
' upgrades(faster turning).
IF (MULTIKEY(SC_LEFT) AND countplayer = 1) OR (MULTIKEY(SC_S) AND countplayer = 2) THEN 
MainShip(countplayer).Angle = MainShip(countplayer).Angle + 22.5/MainShip(countplayer).TurnLevel
IF Frame3 = 7 THEN MainShip(countplayer).Sprite = MainShip(countplayer).Sprite - 1
IF MainShip(countplayer).Sprite < MainShip(countplayer).StartSprite - 1 THEN MainShip(countplayer).Sprite = MainShip(countplayer).StartSprite - 1
GOTO skipreducespr:
END IF
IF (MULTIKEY(SC_RIGHT) AND countplayer = 1) OR (MULTIKEY(SC_F) AND countplayer = 2) THEN 
MainShip(countplayer).Angle = MainShip(countplayer).Angle - 22.5/MainShip(countplayer).TurnLevel
IF Frame3 = 7 THEN MainShip(countplayer).Sprite = MainShip(countplayer).Sprite + 1
IF MainShip(countplayer).Sprite > MainShip(countplayer).StartSprite+1 THEN MainShip(countplayer).Sprite = MainShip(countplayer).StartSprite + 1
GOTO skipreducespr:
END IF
IF MainShip(countplayer).Sprite > MainShip(countplayer).StartSprite THEN MainShip(countplayer).Sprite =  MainShip(countplayer).Sprite - 1
IF MainShip(countplayer).Sprite < MainShip(countplayer).StartSprite THEN MainShip(countplayer).Sprite =  MainShip(countplayer).Sprite + 1
skipreducespr:

' Bad, bad coding! But these two lines are
' the VERY last addition in the code! Bug off!
IF GameMode = 2 THEN
IF countplayer = 1 AND MainShip(2).Alive = FALSE THEN GOTO gotofriction:
IF countplayer = 2 AND MainShip(1).Alive = FALSE THEN GOTO gotofriction:
END IF

' If the player presses up speed up while if
' the player pressed down speed down. Same
' method for using the one IF clause for
' both players.
IF (MULTIKEY(SC_UP) AND countplayer = 1) OR (MULTIKEY(SC_E) AND countplayer = 2) THEN 
MainShip(countplayer).Speed = MainShip(countplayer).Speed + MainShip(countplayer).Acceleration
GOTO skipreducespeed:
END IF
IF (MULTIKEY(SC_DOWN) AND countplayer = 1) OR (MULTIKEY(SC_D) AND countplayer = 2) THEN 
MainShip(countplayer).Speed = MainShip(countplayer).Speed - MainShip(countplayer).Acceleration*0.7
GOTO skipreducespeed:
END IF

gotofriction:
' "Fricton" emulation.
IF MainShip(countplayer).Speed > 0 THEN MainShip(countplayer).Speed = MainShip(countplayer).Speed - MainShip(countplayer).Acceleration*0.5
IF MainShip(countplayer).Speed < 0 THEN MainShip(countplayer).Speed = MainShip(countplayer).Speed + MainShip(countplayer).Acceleration*0.5
IF ABS(MainShip(countplayer).Speed-MainShip(countplayer).Acceleration)<=MainShip(countplayer).Acceleration THEN MainShip(countplayer).Speed = 0
skipreducespeed:

' The next IFs keep the speed in the imagined
' limits. Max. reverse speed is much lower than the
' foward speed, mind you.
IF MainShip(countplayer).Speed > 4.4 THEN MainShip(countplayer).Speed = 4.4
IF MainShip(countplayer).Speed < -MainShip(countplayer).MaxReverse THEN MainShip(countplayer).Speed = -MainShip(countplayer).MaxReverse 
END IF

' Keep the rotation angle between 0 and 360 degrees.
IF MainShip(countplayer).Angle < 0 THEN MainShip(countplayer).Angle = MainShip(countplayer).Angle+360
IF MainShip(countplayer).Angle >= 359 THEN MainShip(countplayer).Angle = 0

' If the player's ship is destroyed or the ship
' is being pulled into the vortex don't move
' it using the next formulas. This third IF
' is an exception for the last stage.
IF countstageend(countplayer) > 130 THEN MainShip(countplayer).Speed = 0
IF MainShip(countplayer).Alive = FALSE THEN MainShip(countplayer).Speed = 0
IF Ship(1).Alive = FALSE AND Stage = 5 THEN MainShip(countplayer).Speed = 0

' Convert the main rotation angle into the
' radians.
radangle! = (MainShip(countplayer).Angle* 3.14159)/180

' Move the camera according to ship's direction,
' ship's speed and main angle.
CamX(countplayer) = CamX(countplayer) - MainShip(countplayer).Speed * SIN(radangle!)
CamY(countplayer) = CamY(countplayer) - MainShip(countplayer).Speed * COS(radangle!)
MainShip(countplayer).RealX = MainShip(countplayer).X + CamX(countplayer)
MainShip(countplayer).RealY = MainShip(countplayer).Y + CamY(countplayer)

' The next IFs keep the ship inside the map
' borders. The map is a rectangle spanning from
' 0 to MapBorder, both in vertical and horizontal
' direction.
IF MainShip(countplayer).RealY<0 THEN MainShip(countplayer).RealY = MapBorder
IF MainShip(countplayer).RealY>MapBorder THEN MainShip(countplayer).RealY = 0
IF MainShip(countplayer).RealX<0 THEN MainShip(countplayer).RealX = MapBorder
IF MainShip(countplayer).RealX>MapBorder THEN MainShip(countplayer).RealX = 0
CamX(countplayer) = MainShip(countplayer).RealX - MainShip(countplayer).X
CamY(countplayer) = MainShip(countplayer).RealY - MainShip(countplayer).Y

' This sub draws the mini map. Two mini maps 
' in two players mode.
DrawMiniMap

IF Stage = 5 AND countstageend(countplayer) = 3 THEN GET (100,20)-(639-100,479-20), FullScreenBuffer(countplayer)

' The next line blits the previously captured
' screen rotated by the main ship angle.
AF2.SprBlit_rotate.solid 320, 240, ScreenBuffer(countplayer), MainShip(countplayer).Angle

' A REMed line that blits the screen both rotated and double sized.
' A faster method for not using Scale2X but results in quite few
' unwanted effects(I need to paste the main ship and text enlarged, etc.).
' AF2.SprBlit_scale.rotate.solid 320, 240, ScreenBuffer, 2, 2, MainShip(countplayer).Angle

' In game mode 2(head on head) when one or the
' other player is dieng don't allow the alive
' one to shoot anymore.
IF GameMode = 2 THEN
IF countplayerdeath(1) > 0 OR countplayerdeath(2) > 0 THEN GOTO skipweaponrestore:    
END IF

IF MainShip(countplayer).Alive = TRUE THEN

' The next lines control the shooting. Note how extra
' projectiles are initiated on higher weapon levels.
' Again, same method to use one IF clause for both
' players in two players mode(by using the countplayer
' variable as a condition).
IF (MULTIKEY(SC_ENTER) AND MainShip(countplayer).Reload = 0 AND countplayer = 1) OR (MULTIKEY(SC_Q) AND MainShip(countplayer).Reload = 0 AND countplayer = 2) THEN
MainShip(countplayer).Reload = 5
MainShip(countplayer).Shots = MainShip(countplayer).Shots + 1
MainShip(countplayer).Battery = MainShip(countplayer).Battery + 0.52
IF MainShip(countplayer).Battery >= MainShip(countplayer).MaxBattery THEN MainShip(countplayer).Reload = 14
IF MainShip(countplayer).Battery > MainShip(countplayer).MaxBattery THEN MainShip(countplayer).Battery = MainShip(countplayer).MaxBattery
playsample (sample(1))
InitiateProjectile MainShip(countplayer).RealX+10, MainShip(countplayer).RealY+8, MainShip(countplayer).ShipProj, MainShip(countplayer).Angle, 0, 45, MainShip(countplayer).WeaponPower
IF MainShip(countplayer).WeaponLevel=2 THEN InitiateProjectile MainShip(countplayer).RealX+10, MainShip(countplayer).RealY+8, MainShip(countplayer).ShipProj, MainShip(countplayer).Angle-180, 0, 45, MainShip(countplayer).WeaponPower
IF MainShip(countplayer).WeaponLevel=3 THEN 
InitiateProjectile MainShip(countplayer).RealX+10, MainShip(countplayer).RealY+8, MainShip(countplayer).ShipProj, MainShip(countplayer).Angle-90, 0, 45, MainShip(countplayer).WeaponPower
InitiateProjectile MainShip(countplayer).RealX+10, MainShip(countplayer).RealY+8, MainShip(countplayer).ShipProj, MainShip(countplayer).Angle+90, 0, 45, MainShip(countplayer).WeaponPower
END IF
IF MainShip(countplayer).WeaponLevel=4 THEN 
InitiateProjectile MainShip(countplayer).RealX+10, MainShip(countplayer).RealY+8, MainShip(countplayer).ShipProj, MainShip(countplayer).Angle-20, 0, 45, MainShip(countplayer).WeaponPower
InitiateProjectile MainShip(countplayer).RealX+10, MainShip(countplayer).RealY+8, MainShip(countplayer).ShipProj, MainShip(countplayer).Angle+20, 0, 45, MainShip(countplayer).WeaponPower
END IF
END IF
IF (MULTIKEY(SC_ENTER) AND countplayer = 1) OR (MULTIKEY(SC_Q) AND countplayer = 2) THEN GOTO skipweaponrestore:
IF MainShip(countplayer).Reload = 0 THEN MainShip(countplayer).Battery = MainShip(countplayer).Battery - 0.4
skipweaponrestore:
IF MainShip(countplayer).Battery < 0 THEN MainShip(countplayer).Battery = 0

' The next lines paste the proper main ship 
' sprite and only if the main ship is not being 
' pulled into the vortex(thus the usage of 
' countstageend(countplayer) variable.
IF MainShip(countplayer).Alive = TRUE THEN
IF (MULTIKEY(SC_UP) AND countstageend(countplayer)<131 AND countplayer =1) OR (MULTIKEY(SC_E) AND countstageend(countplayer)<131 AND countplayer = 2) THEN AF2.SprBlit MainShip(countplayer).X, MainShip(countplayer).Y, @Sprites1.p_data[Sprites1.p_dataindex[4-1]], GFX_v, GFX_h
IF countstageend(countplayer)<131 THEN AF2.SprBlit MainShip(countplayer).X, MainShip(countplayer).Y, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(countplayer).Sprite-1]], GFX_v, GFX_h
END IF

' When the vortex it pulling the ship into the
' new sector paste the main ship as scaled
' and reduce the scale in every loop until
' it disappers into the vortex. When it
' completely disappears trigger the
' countstageend(countplayer) variable(=132).
IF countstageend(countplayer)>130 AND MainShip(countplayer).VortexScale>0 THEN
AF2.SprBlit_scale.rotate MainShip(countplayer).X+10, MainShip(countplayer).Y+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(countplayer).Sprite-1]], MainShip(countplayer).VortexScale, MainShip(countplayer).VortexScale, 0 
MainShip(countplayer).VortexScale = MainShip(countplayer).VortexScale - 0.05
IF MainShip(countplayer).VortexScale < 0 THEN MainShip(countplayer).VortexScale = 0
IF MainShip(countplayer).VortexScale = 0 THEN 
countstageend(countplayer) = 132
pseconds(countplayer) = seconds
END IF
IF MainShip(countplayer).RealX+10>vorx! THEN MainShip(countplayer).RealX = MainShip(countplayer).RealX - 1
IF MainShip(countplayer).RealX+10<vorx! THEN MainShip(countplayer).RealX = MainShip(countplayer).RealX + 1
IF MainShip(countplayer).RealY+8>vory! THEN MainShip(countplayer).RealY = MainShip(countplayer).RealY - 1
IF MainShip(countplayer).RealY+8<vory! THEN MainShip(countplayer).RealY = MainShip(countplayer).RealY + 1
CamX(countplayer) = MainShip(countplayer).RealX - MainShip(countplayer).X
CamY(countplayer) = MainShip(countplayer).RealY - MainShip(countplayer).Y
END IF

END IF ' End of IF the main ship is alive.

' The next lines paste the proper text on the
' screen(ship's status) in one player mode.
IF numofplayers = 1 THEN
procentshield = (100/MainShip(countplayer).MaxShield)*MainShip(countplayer).Shield
'IF procentshield < 6 AND Frame1 = 2 AND Frame2 = 2 THEN InitiateExplosion MainShip(countplayer).RealX + 10, MainShip(countplayer).RealY + 7, 3, 5
procentbattery = 100-(100/MainShip(countplayer).MaxBattery)*MainShip(countplayer).Battery
AF2.PP256fntSP_tr.fadecust "Shield: "+STR$(procentshield)+"%", 160+5, 325, 0, 0, 3, Font1, GFX_v, GFX_h 
IF procentshield<20 AND Frame3 < 5 THEN AF2.PP256fntSP_tr.fadecust "        "+STR$(procentshield)+"%", 160+5, 325, 0, 0, 5, Font1, GFX_v, GFX_h 
IF MainShip(countplayer).Shield = 0 THEN AF2.PP256fntSP_tr.fadecust "        "+STR$(procentshield)+"%", 160+5, 325, 0, 0, 5, Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Battery: "+STR$(procentbattery)+"%", 160+5, 335, 0, 0, 3, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Reserve energy: "+STR$(MainShip(countplayer).Energy)+" Xl", 160+5, 345, 0, 0, 3, Font1, GFX_v, GFX_h 
sxpos% = MapBorder/2 - MainShip(countplayer).RealX
sypos% = MapBorder/2 - MainShip(countplayer).RealY
plusx$ = "-"
plusy$ = "-"
zerosx$ = ""
zerosy$ = ""
IF sxpos%>=0 THEN plusx$ = "+"
IF sypos%>=0 THEN plusy$ = "+"
IF ABS(sxpos%)<1000 THEN zerosx$ = "0"
IF ABS(sxpos%)<100 THEN zerosx$ = "00"
IF ABS(sxpos%)<10 THEN zerosx$ = "000"
IF ABS(sypos%)<1000 THEN zerosy$ = "0"
IF ABS(sypos%)<100 THEN zerosy$ = "00"
IF ABS(sypos%)<10 THEN zerosy$ = "000"
AF2.PP256fntSP_tr.fadecust "X: "+plusx$+zerosx$+STR$(ABS(sxpos%)), 160+5, 121, 0, 0, 3, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Y: "+plusy$+zerosy$+STR$(ABS(sypos%)), 160+5, 131, 0, 0, 3, Font1, GFX_v, GFX_h 
zeross$ = ""
IF ABS(MainShip(countplayer).Score)<10000 THEN zeross$ = "0"
IF ABS(MainShip(countplayer).Score)<1000 THEN zeross$ = "00"
IF ABS(MainShip(countplayer).Score)<100 THEN zeross$ = "000"
IF ABS(MainShip(countplayer).Score)<10 THEN zeross$ = "0000"
AF2.PP256fntSP_tr.fadecust "Score: "+zeross$+STR$(MainShip(countplayer).Score), 380, 122, 0, 0, 3, Font1, GFX_v, GFX_h 

IF countplayerdeath(countplayer) > 34 THEN AF2.PP256fntSP_tr.fadecust "G A M E  O V E R", 160+5, 235, 0, 1, 0, Font1, GFX_v, GFX_h 
IF countstageend(countplayer) > 10 AND countstageend(countplayer) < 120 AND Stage < 5 THEN AF2.PP256fntSP_tr.fadecust "Sector Cleared - A Vortex Detected", 160+5, 235, 0, 1, 0, Font1, GFX_v, GFX_h 
IF CountStartStage > 0 AND Stage < 5 THEN AF2.PP256fntSP_tr.fadecust "Sector "+STR$(Stage), 160+5, 235, 0, 1, 0, Font1, GFX_v, GFX_h 
IF CountStartStage > 0 AND Stage = 5 THEN AF2.PP256fntSP_tr.fadecust "Unknown Location", 160+5, 235, 0, 1, 0, Font1, GFX_v, GFX_h 

GET (160,120)-(480,360), ScreenBuffer(1) ' FINAL capturing of the
                                         ' screen data in one player
                                         ' mode.
END IF

procentshield = (100/MainShip(countplayer).MaxShield)*MainShip(countplayer).Shield
IF procentshield<20 AND warningmsg(countplayer) = TRUE THEN
warningmsg(countplayer) = FALSE
playsample (sample(14))
END IF

' In two players mode we need to capture two screens into two
' separate buffers.
IF numofplayers = 2 THEN GET (240,120)-(400,360), ScreenBuffer(countplayer)

NEXT countplayer ' End looping through the players(from 1 to 2).

' In GraphicMode 1(Scale2X) put the captured graphic into the
' upper left corner of the screen and scale it by 2.
' In two players mode we need to paste two screen buffers.
IF GraphicMode = 1 THEN
IF numofplayers = 1 THEN PUT (0,0), ScreenBuffer(1), PSET
IF numofplayers = 2 THEN 
PUT (0,0), ScreenBuffer(2), PSET
PUT (160,0), ScreenBuffer(1), PSET
END IF
AF2.Scale2x_320x240
IF numofplayers = 2 THEN
' The next lines paste the ship data and
' neccessary messages if they are
' activated in real size(un-scaled).
PrintShipStatus 3

END IF
END IF

' In graphic mode 2 we stretch the captured screen buffer by 2.
' Same thing for the two players mode but we stretch two screen
' buffers.
IF GraphicMode = 2 THEN
IF numofplayers = 1 THEN AF2.SprBlit_scale.solid 320, 240, ScreenBuffer(1), 2, 2
IF numofplayers = 2 THEN
AF2.SprBlit_scale.solid 160, 240, ScreenBuffer(2), 2, 2
AF2.SprBlit_scale.solid 480, 240, ScreenBuffer(1), 2, 2
PrintShipStatus 3

END IF
END IF

'AF2.SprBlit_rotate.solid 560, 410, MiniMapBuffer, MainShip(countplayer).Angle

' Paste the map buffers(captured in DrawMiniMap sub) according
' to num. of players.
IF numofplayers = 1 THEN
AF2.SprBlit_rotate.solid 570, 420, MiniMapBuffer(1), MainShip(1).Angle
PSET (570, 420), 79
END IF
IF numofplayers = 2 THEN
AF2.SprBlit_rotate.solid 253, 420, MiniMapBuffer(2), MainShip(2).Angle
PSET (253, 420), 79
AF2.SprBlit_rotate.solid 570, 420, MiniMapBuffer(1), MainShip(1).Angle
PSET (570, 420), 79
' Paste the sky blue line between two screens in two players mode.
LINE (317,0)-(323,480), 175, BF
LINE (316,0)-(316,480), 173
LINE (324,0)-(324,480), 173
LINE (315,0)-(315,480), 171
LINE (325,0)-(325,480), 171
LINE (314,0)-(314,480), 169
LINE (326,0)-(326,480), 169

IF GameMode = 1 AND countplayerdeath(1) > 34 AND countplayerdeath(2) > 34 THEN AF2.PP256fntSP_tr.fadecust "G A M E  O V E R", 160+5, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
IF GameMode = 2 AND countplayerdeath(1) > 34 AND MainShip(2).Alive = TRUE THEN AF2.PP256fntSP_tr.fadecust "Left Player Wins!", 160+5, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
IF GameMode = 2 AND countplayerdeath(2) > 34 AND MainShip(1).Alive = TRUE THEN AF2.PP256fntSP_tr.fadecust "Right Player Wins!", 160+5, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
IF GameMode = 2 AND countplayerdeath(1) > 34 AND countplayerdeath(2) > 34 THEN AF2.PP256fntSP_tr.fadecust "Double Kill!", 160+5, 215, 0, 1, 0, Font1, GFX_v, GFX_h 

IF countstageend(1) > 10 AND countstageend(1) < 129 AND Stage < 5 THEN AF2.PP256fntSP_tr.fadecust "Sector Cleared - A Vortex Detected", 20, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
IF CountStartStage > 0 AND Stage < 5 AND GameMode = 1 THEN AF2.PP256fntSP_tr.fadecust "Sector "+STR$(Stage), 140, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
IF CountStartStage > 0 AND GameMode = 2 THEN AF2.PP256fntSP_tr.fadecust "Destroy The Opponent!", 140, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
IF CountStartStage > 0 AND Stage = 5 AND GameMode = 1 THEN AF2.PP256fntSP_tr.fadecust "Unknown Location", 140, 215, 0, 1, 0, Font1, GFX_v, GFX_h 
END IF

IF FPSCounter = TRUE THEN AF2.PP256fntSP_tr.fadecust "FPS: "+STR$(FPS2), 580, 30, 0, 0, 0, Font1, GFX_v, GFX_h 

IF MULTIKEY(SC_F2) AND FPSCounter = FALSE THEN 
FPSCounter = TRUE
ELSEIF MULTIKEY(SC_F2) AND FPSCounter = TRUE THEN 
FPSCounter = FALSE 
END IF
WHILE MULTIKEY(SC_F2)
WEND

'IF MULTIKEY(SC_E) THEN startminimapy = startminimapy + 1
'IF MULTIKEY(SC_W) THEN startminimapy = startminimapy - 1
'IF MULTIKEY(SC_S) THEN startminimapx = startminimapx - 1
'IF MULTIKEY(SC_D) THEN startminimapx = startminimapx + 1

' An extra loop for both players that enables their
' "death" animation represented by several explosions.
FOR countplayer = 1 TO numofplayers
IF MainShip(countplayer).Alive = FALSE THEN countplayerdeath(countplayer) = countplayerdeath(countplayer) + 1
IF countplayerdeath(countplayer) > 120 THEN countplayerdeath(countplayer) = 120
IF countplayerdeath(countplayer) = 1 THEN InitiateExplosion MainShip(countplayer).RealX-10+10, MainShip(countplayer).RealY-10+7, 2, 5-countplayer
IF countplayerdeath(countplayer) = 3 THEN InitiateExplosion MainShip(countplayer).RealX-15+10, MainShip(countplayer).RealY-13+7, 2, 5-countplayer
IF countplayerdeath(countplayer) = 5 THEN InitiateExplosion MainShip(countplayer).RealX-8+10, MainShip(countplayer).RealY-7+7, 2, 5-countplayer
IF countplayerdeath(countplayer) = 6 THEN InitiateExplosion MainShip(countplayer).RealX-3+10, MainShip(countplayer).RealY-5+7, 2, 5-countplayer
IF countplayerdeath(countplayer) = 10 THEN InitiateExplosion MainShip(countplayer).RealX-5+10, MainShip(countplayer).RealY-15+7, 2, 5-countplayer
IF Frame5 = 1 AND countplayerdeath(countplayer)> 8 AND countplayerdeath(countplayer) < 30 THEN
explx! = int(rnd * 20) - 10 + MainShip(countplayer).RealX
exply! = int(rnd * 20) - 10 + MainShip(countplayer).RealY
InitiateExplosion explx!, exply!-3, 2, 5-countplayer
END IF
NEXT countplayer

' If the player's ship's destruction animation has
' finished, or in two player's mode both ship
' are destroyed and exploded, completely end game.
IF (countplayerdeath(1) = 120 AND numofplayers = 1) OR (countplayerdeath(1) = 120 AND countplayerdeath(2) = 120 AND numofplayers = 2) THEN
stopStreamMusic
BreakScreen
IF PlayingAgain = FALSE THEN WriteHighScore
EXIT SUB
END IF

IF numofplayers = 1 AND countplayerdeath(1) = 15 THEN stopStreamMusic
IF numofplayers = 2 AND countplayerdeath(1) = 15 AND MainShip(2).Alive = FALSE THEN stopStreamMusic
IF numofplayers = 2 AND countplayerdeath(2) = 15 AND MainShip(1).Alive = FALSE THEN stopStreamMusic

IF GameMode = 2 THEN
IF countplayerdeath(1) = 30 OR countplayerdeath(2) = 30 THEN stopStreamMusic
IF countplayerdeath(1) = 120 OR countplayerdeath(2) = 120 THEN
BreakScreen
EXIT SUB
END IF
END IF

'IF MULTIKEY(SC_K) THEN
'FOR killship = 1 TO numofships
'Ship(killship).Alive = FALSE
'WHILE MULTIKEY(SC_K)
'WEND
'NEXT killship
'END IF

' If a phase has been completed(all enemies 
' destroyed) spawn new group(s) of enemies. 
' Each stage features 3 phases.
IF PhaseDone = TRUE THEN NewPhase

' If a phase 3 has been completed start raising
' the countstageend(1/2) variables. They rise to
' 130. They can become 132 only if one of the 
' ships enters the "end stage" vortex. In one
' player mode countstageend(2) is not considered
' at all.
IF PhaseDone = TRUE AND PhaseNumber = 3 AND countstageend(1)<130 AND countstageend(2)<130 THEN 
countstageend(1) = countstageend(1) + 1
countstageend(2) = countstageend(2) + 1
END IF

' Stage 5, a special way of stage ending!
IF (Ship(1).Alive = FALSE AND PhaseNumber = 1 AND Stage = 5) THEN 
countstageend(1) = countstageend(1) + 1
countstageend(2) = countstageend(2) + 1
END IF

' In game mode 2(head on head) we add ships 
' into the play field when there is less 
' than 4 of them in it.
IF GameMode = 2 THEN AddShips

' If the stage has been complted and 6
' loops have passed since the death of
' the last ship spawn the "end stage"
' vortex through which the main ship
' needs to pass. It's spawn as a new
' planet.
IF countstageend(1) = 6 AND Stage < 5 THEN SpawnVortex

' If countstageend(1) is 132(the stage has
' been completed, the main ship has
' entered the vortex and it has disappeared
' in it) end stage. In two players mode
' both ships need to enter the vortex
' (countstageend(1) and countstageend(2) need
' to be 132).
IF (countstageend(1) = 132 AND numofplayers = 1) OR (countstageend(1) = 132 AND countstageend(2) = 132 AND numofplayers = 2) OR (countstageend(1) = 132 AND MainShip(2).Alive = FALSE AND numofplayers = 2) OR (MainShip(1).Alive = FALSE AND countstageend(2) = 132 AND numofplayers = 2) THEN
stopStreamMusic
BreakScreen
UpgradeShipScreen
Stage = Stage + 1
nextstage:
InitStage
IF PlayingAgain = FALSE AND Stage = 5 THEN PreStage5Anim
GOTO startmainloop:
END IF

' If you have finished the 5th stage
' break the screen and display the end
' game screen.
IF Stage = 5 AND countstageend(1) = 5 THEN
' If you finished the game for the first time...
EndGame
IF PlayingAgain = FALSE THEN 
BreakScreen
WriteHighScore
PlayAgainMenu
END IF

' If you decided to play the game once more
' or you already finished it twice...
IF PlayingAgain = TRUE THEN
BreakScreen
Stage = 1
FOR countplayer = 1 TO numofplayers
'MainShip(countplayer).Score = 0
NEXT countplayer
GOTO nextstage:
END IF

EXIT SUB
END IF

JoinScreen

FOR countplayer = 1 TO numofplayers
IF MULTIKEY(SC_ESCAPE) AND MainShip(countplayer).Alive = TRUE THEN 
IF PlaySound = TRUE THEN FSOUND_SetPaused(1, 1)    
GOTO exitmainloop:
END IF
NEXT countplayer

workpage xor = 1

IF MULTIKEY(SC_F1) THEN
BSAVE "screenshot"+LTRIM$(RTRIM$(STR$(sshot)))+".bmp", 0, 307204
sshot=sshot+1
WHILE MULTIKEY(SC_F1)
WEND
END IF

do 
loop until timer& - st >= (1/fpslimit) 
st = timer& 

SLEEP 1

gobackmainloop:
LOOP

exitmainloop:
DO
IF PlaySound = TRUE THEN FSOUND_Update
screenset workpage, workpage xor 1
AF2.ClearScreen 0 
IF numofplayers = 1 THEN AF2.SprBlit_Trans 0, 0, ScreenBuffer(1), GFX_v, GFX_h 
IF numofplayers = 2 THEN
AF2.SprBlit_Trans 0, 0, ScreenBuffer(2), GFX_v, GFX_h 
AF2.SprBlit_Trans 160, 0, ScreenBuffer(1), GFX_v, GFX_h 
END IF
AF2.PP256fntSP_tr.fadecust "Quit(Y/N)?", 120, 115, 0, 0, 0, Font1, GFX_v, GFX_h
AF2.Scale2x_320x240
IF numofplayers = 2 THEN PrintShipStatus 6
workpage xor = 1   
IF MULTIKEY(SC_N) THEN 
IF PlaySound = TRUE THEN FSOUND_SetPaused(1, 0) 
GOTO gobackmainloop:
END IF
do 
loop until timer& - st >= (1/fpslimit) 
st = timer& 
SLEEP 1  

LOOP UNTIL MULTIKEY(SC_Y) OR MULTIKEY(SC_Z)
BreakScreen

END SUB

SUB InitiateProjectile (px!, py!, ptyp, pangle!, pmode, pduration, ppower!)

FOR initproj = 1 TO numofprojectiles

IF Projectile(initproj).Locked = FALSE THEN
IF pangle!<0 THEN pangle! = pangle! + 360
IF pangle!>359 THEN pangle! = pangle! - 360
Projectile(initproj).Locked = TRUE
Projectile(initproj).X = px!
Projectile(initproj).Y = py!
Projectile(initproj).Typ = ptyp
Projectile(initproj).LifeTime = pduration
Projectile(initproj).WeaponPower = ppower!
IF Projectile(initproj).Typ < 3 THEN
Projectile(initproj).Sprite = ptyp
Projectile(initproj).Angle = -pangle!
Projectile(initproj).Speed = 3.5 + MainShip(countplayer).Speed
END IF
IF Projectile(initproj).Typ = 3 THEN
Projectile(initproj).Sprite = 3
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.2 + pmode
END IF
IF Projectile(initproj).Typ = 4 THEN
Projectile(initproj).Sprite = 4
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2 + pmode
END IF
IF Projectile(initproj).Typ = 5 THEN
Projectile(initproj).Sprite = 5
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.6 + pmode
END IF
IF Projectile(initproj).Typ = 6 THEN
playsample (sample(7))
Projectile(initproj).Sprite = 6
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 3.6 + pmode
END IF
IF Projectile(initproj).Typ = 7 THEN
Projectile(initproj).Sprite = 7
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 3 + pmode
END IF
IF Projectile(initproj).Typ = 8 THEN
Projectile(initproj).Sprite = 8
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 3 + pmode
END IF
IF Projectile(initproj).Typ = 9 THEN
playsample (sample(8))
Projectile(initproj).Sprite = 9
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 1 + pmode
Projectile(initproj).TurnLevel = 3
END IF
IF Projectile(initproj).Typ = 10 THEN
playsample (sample(4))
Projectile(initproj).Sprite = 10
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.8 + pmode
END IF
IF Projectile(initproj).Typ = 11 THEN
playsample (sample(4))
Projectile(initproj).Sprite = 8
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.1 + pmode
END IF
IF Projectile(initproj).Typ = 12 THEN
playsample (sample(7))
Projectile(initproj).Sprite = 11
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.4 + pmode
END IF
IF Projectile(initproj).Typ = 13 THEN
playsample (sample(7))
Projectile(initproj).Sprite = 12
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.6 + pmode
END IF
IF Projectile(initproj).Typ = 14 THEN
Projectile(initproj).Sprite = 13
Projectile(initproj).Angle = pangle!
Projectile(initproj).Speed = 2.3 + pmode
END IF
EXIT SUB
END IF

NEXT initproj

END SUB

SUB ProjectileLayer ()

FOR countproj = 1 TO numofprojectiles
    
IF Projectile(countproj).Locked = FALSE THEN goto skiptonextproj:

projspr = Projectile(countproj).Sprite

ProjectileAI countproj

IF numofplayers = 2 AND countplayer = 2 THEN GOTO skiptoprojdraw:

Projectile(countproj).LifeTime = Projectile(countproj).LifeTime - 1
IF Projectile(countproj).LifeTime < 0 THEN Projectile(countproj).Locked = FALSE

radpangle! = (Projectile(countproj).Angle* 3.14159)/180
Projectile(countproj).X = Projectile(countproj).X + Projectile(countproj).Speed * SIN(radpangle!)
Projectile(countproj).Y = Projectile(countproj).Y - Projectile(countproj).Speed * COS(radpangle!)

' Projectiles under 3 and from players' ships.
IF Projectile(countproj).Typ<3 THEN
    
' Loop through the enemy ships to check for
' collision.
FOR hitship = 1 TO numofships
' If a projecile is active(this prevents one 
' projectile to damage more ships), current 
' ship is alive and one loop has passed since 
' the projectile has been launched check for 
' collision with the enemy ship.
IF Projectile(countproj).Locked = TRUE AND Ship(hitship).Alive = TRUE AND Projectile(countproj).LifeTime<49 THEN
IF Ship(hitship).Sprite>0 AND Ship(hitship).Sprite<15 AND AF2.SprCollide(Projectile(countproj).X-3, Projectile(countproj).Y-5, @ProjSprite.p_data[ProjSprite.p_dataindex[Projectile(countproj).Sprite-1]], Ship(hitship).X-Ship(hitship).CenterX, Ship(hitship).Y-Ship(hitship).CenterY, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(hitship).Sprite-1]]) THEN 
' Reduce the ship's shield by the power of
' the projectile(always 1 with players' ships).
Ship(hitship).Shield = Ship(hitship).Shield - Projectile(countproj).WeaponPower

' Exception!!! Stage 5. The space module can't be
' damaged until the big ship is destroyed!
IF Ship(hitship).Typ = 13 AND Ship(2).Alive = TRUE THEN Ship(hitship).Shield = Ship(hitship).Shield + Projectile(countproj).WeaponPower

' "Destroy" the projectile since a hit
' has happened.
Projectile(countproj).Locked = FALSE
' Spawn the small explosion.
InitiateExplosion Projectile(countproj).X-5, Projectile(countproj).Y-5, 1, 5

' If ship's shield has depleted destory it!
IF Ship(hitship).Shield <= 0 THEN 
Ship(hitship).Alive = FALSE
' Add score to the player that has made 
' the hit(projectile typ 1 is player's
' one projectile while projectile typ 2 is
' player's two projectile).
IF Projectile(countproj).Typ = 1 THEN MainShip(1).Score = MainShip(1).Score + Ship(hitship).Score
IF Projectile(countproj).Typ = 2 THEN MainShip(2).Score = MainShip(1).Score + Ship(hitship).Score

' Exception! Stage 5. Change the look of the space module
' (disable the shield look) when the big ship
' is destroyed.
IF Ship(hitship).Typ = 11 THEN Ship(1).Sprite = Ship(1).Sprite - 1
' If the destroyed ship is a "pickup carrier"
' spawn a pickup.
IF Ship(hitship).Energy > 0 THEN InitiatePickup Ship(hitship).X-7, Ship(hitship).Y-7, Ship(hitship).Energy
' Spawn appropriate explosions according to
' destroyed type of the ship.
IF Ship(hitship).Typ < 4 OR Ship(hitship).Typ = 8 OR Ship(hitship).Typ = 9 OR Ship(hitship).Typ = 12 THEN 
InitiateExplosion Ship(hitship).X-10, Ship(hitship).Y-10, 2, 6
END IF
IF Ship(hitship).Typ = 4 THEN 
InitiateExplosion Ship(hitship).X-10+10*SIN(Ship(hitship).Angle), Ship(hitship).Y-10-10*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-10*SIN(Ship(hitship).Angle), Ship(hitship).Y-10+10*COS(Ship(hitship).Angle), 2, 6
END IF
IF Ship(hitship).Typ = 5 THEN 
InitiateExplosion Ship(hitship).X-10+6*COS(Ship(hitship).Angle), Ship(hitship).Y-10+6*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-6*COS(Ship(hitship).Angle), Ship(hitship).Y-10-6*SIN(Ship(hitship).Angle), 2, 6
END IF
IF Ship(hitship).Typ > 5 AND  Ship(hitship).Typ < 8 THEN 
InitiateExplosion Ship(hitship).X-10+8*COS(Ship(hitship).Angle), Ship(hitship).Y-10+8*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-8*COS(Ship(hitship).Angle), Ship(hitship).Y-10-8*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10+8*SIN(Ship(hitship).Angle), Ship(hitship).Y-10-8*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-8*SIN(Ship(hitship).Angle), Ship(hitship).Y-10+8*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10, Ship(hitship).Y-10, 2, 6
END IF
IF Ship(hitship).Typ = 10 THEN
InitiateExplosion Ship(hitship).X-10+6*COS(Ship(hitship).Angle), Ship(hitship).Y-10+6*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-6*COS(Ship(hitship).Angle), Ship(hitship).Y-10-6*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10+6*SIN(Ship(hitship).Angle), Ship(hitship).Y-10-6*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10, Ship(hitship).Y-10, 2, 6
END IF
IF Ship(hitship).Typ = 11 THEN 
InitiateExplosion Ship(hitship).X-10+8*COS(Ship(hitship).Angle), Ship(hitship).Y-10+8*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-8*COS(Ship(hitship).Angle), Ship(hitship).Y-10-8*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10+8*SIN(Ship(hitship).Angle), Ship(hitship).Y-10-8*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-8*SIN(Ship(hitship).Angle), Ship(hitship).Y-10+8*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10+18*COS(Ship(hitship).Angle), Ship(hitship).Y-10+18*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-18*COS(Ship(hitship).Angle), Ship(hitship).Y-10-18*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10+18*SIN(Ship(hitship).Angle), Ship(hitship).Y-10-18*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10, Ship(hitship).Y-10, 2, 6
ExtraExplosion = 20
END IF
IF Ship(hitship).Typ = 13 THEN 
InitiateExplosion Ship(hitship).X-10+6*COS(Ship(hitship).Angle), Ship(hitship).Y-10+6*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-6*COS(Ship(hitship).Angle), Ship(hitship).Y-10-6*SIN(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10+6*SIN(Ship(hitship).Angle), Ship(hitship).Y-10-6*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10-6*SIN(Ship(hitship).Angle), Ship(hitship).Y-10+6*COS(Ship(hitship).Angle), 2, 6
InitiateExplosion Ship(hitship).X-10, Ship(hitship).Y-10, 2, 6
END IF

END IF ' End of if the hit ship is destroyed
END IF ' End of if sprites(projectile and 
       ' the enemy ship) are colliding
END IF ' End of if projectile active, ship alive, ... 
NEXT hitship

END IF ' End of if the current projectile is from 
       ' the player's ships.

skiptoprojdraw:

' If a projectile originates from an
' enemy ships check collison with the
' players' ships.
IF Projectile(countproj).Typ>2 THEN
IF MainShip(countplayer).Alive = TRUE AND AF2.SprCollide(Projectile(countproj).X-3, Projectile(countproj).Y-5, @ProjSprite.p_data[ProjSprite.p_dataindex[Projectile(countproj).Sprite-1]], MainShip(countplayer).RealX, MainShip(countplayer).RealY, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(countplayer).Sprite-1]]) THEN 
MainShip(countplayer).Shield = MainShip(countplayer).Shield - Projectile(countproj).WeaponPower
IF MainShip(countplayer).Shield <= 0 THEN 
MainShip(countplayer).Shield = 0
MainShip(countplayer).Alive = FALSE
END IF
Projectile(countproj).Locked = FALSE
InitiateExplosion Projectile(countproj).X-5, Projectile(countproj).Y-5, 1, 5
END IF
END IF

' In game mode 2(head to head) players can
' damage each other. Projectile typ 1 can damage
' player 2 while projectile typ 2 can damage
' player 1.
IF GameMode = 2 AND Projectile(countproj).Typ<3 THEN
IF Projectile(countproj).LifeTime<49 AND Projectile(countproj).Typ = 1 AND MainShip(2).Alive = TRUE AND AF2.SprCollide(Projectile(countproj).X-3, Projectile(countproj).Y-5, @ProjSprite.p_data[ProjSprite.p_dataindex[Projectile(countproj).Sprite-1]], MainShip(2).RealX, MainShip(2).RealY, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]]) THEN 
MainShip(2).Shield = MainShip(2).Shield - Projectile(countproj).WeaponPower
IF MainShip(2).Shield <= 0 THEN 
MainShip(2).Shield = 0
MainShip(2).Alive = FALSE
END IF
Projectile(countproj).Locked = FALSE
InitiateExplosion Projectile(countproj).X-5, Projectile(countproj).Y-5, 1, 5
END IF
IF Projectile(countproj).LifeTime<49 AND Projectile(countproj).Typ = 2 AND MainShip(1).Alive = TRUE AND AF2.SprCollide(Projectile(countproj).X-3, Projectile(countproj).Y-5, @ProjSprite.p_data[ProjSprite.p_dataindex[Projectile(countproj).Sprite-1]], MainShip(1).RealX, MainShip(1).RealY, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]]) THEN 
MainShip(1).Shield = MainShip(1).Shield - Projectile(countproj).WeaponPower
IF MainShip(1).Shield <= 0 THEN 
MainShip(1).Shield = 0
MainShip(1).Alive = FALSE
END IF
Projectile(countproj).Locked = FALSE
InitiateExplosion Projectile(countproj).X-5, Projectile(countproj).Y-5, 1, 5
END IF
END IF

' Keep the current projectile within the map
' borders.
IF Projectile(countproj).Y<0 THEN Projectile(countproj).Y = MapBorder
IF Projectile(countproj).Y>MapBorder THEN Projectile(countproj).Y = 0
IF Projectile(countproj).X<0 THEN Projectile(countproj).X = MapBorder
IF Projectile(countproj).X>MapBorder THEN Projectile(countproj).X = 0

' Draw the projectile.
AF2.SprBlit_rotate Projectile(countproj).X-CamX(countplayer),Projectile(countproj).Y-CamY(countplayer), @ProjSprite.p_data[ProjSprite.p_dataindex[projspr-1]], Projectile(countproj).Angle

' circularmap FOR loop is used to enable 
' the illusion of the circular map
' by pasting the projectiles in 8 sectors
' around the main map sector. No optimizing
' was done so projectiles are drawn no matter
' of the player can see them. Does no effect
' on the speed of the engine.
FOR circularmap = 1 TO 8
SELECT CASE circularmap
CASE 1
MapBorder1 = MapBorder
MapBorder2 = 0
CASE 2
MapBorder1 = -MapBorder
MapBorder2 = 0
CASE 3
MapBorder1 = 0
MapBorder2 = MapBorder
CASE 4
MapBorder1 = 0
MapBorder2 = -MapBorder
CASE 5
MapBorder1 = MapBorder
MapBorder2 = MapBorder
CASE 6
MapBorder1 = -MapBorder
MapBorder2 = -MapBorder
CASE 7
MapBorder1 = -MapBorder
MapBorder2 = MapBorder
CASE 8
MapBorder1 = MapBorder
MapBorder2 = -MapBorder
END SELECT
AF2.SprBlit_rotate Projectile(countproj).X-CamX(countplayer)+MapBorder1,Projectile(countproj).Y-CamY(countplayer)+MapBorder2, @ProjSprite.p_data[ProjSprite.p_dataindex[projspr-1]], Projectile(countproj).Angle
NEXT circularmap

skiptonextproj:
NEXT countproj
    
END SUB

SUB StarsLayer ()

' A sub that draws the stars during the
' game. They scroll 2 or 4 times slower
' than the camera moves, which means
' there is two layers of stars. Hopefully,
' this gives a certain depth effect.

FOR cstar = 1 TO 400

scolor = Star(cstar).SColor
PSET (Star(cstar).X-CamX(countplayer)/4, Star(cstar).Y-CamY(countplayer)/4),scolor
FOR circularmap = 1 TO 8
SELECT CASE circularmap
CASE 1
MapBorder1 = MapBorder
MapBorder2 = 0
CASE 2
MapBorder1 = -MapBorder
MapBorder2 = 0
CASE 3
MapBorder1 = 0
MapBorder2 = MapBorder
CASE 4
MapBorder1 = 0
MapBorder2 = -MapBorder
CASE 5
MapBorder1 = MapBorder
MapBorder2 = MapBorder
CASE 6
MapBorder1 = -MapBorder
MapBorder2 = -MapBorder
CASE 7
MapBorder1 = -MapBorder
MapBorder2 = MapBorder
CASE 8
MapBorder1 = MapBorder
MapBorder2 = -MapBorder
END SELECT
IF ABS(MainShip(countplayer).X - Star(cstar).X-(MapBorder1/4)+CamX(countplayer)/4) < 300 AND ABS(MainShip(countplayer).Y - Star(cstar).Y-(MapBorder2/4)+CamY(countplayer)/4) < 300 THEN
PSET (Star(cstar).X+(MapBorder1/4)-CamX(countplayer)/4, Star(cstar).Y+(MapBorder2/4)-CamY(countplayer)/4),scolor
END IF
NEXT circularmap

NEXT cstar

FOR cstar = 401 TO 800

scolor = Star(cstar).SColor
LINE (Star(cstar).X-1-CamX(countplayer)/2, Star(cstar).Y-CamY(countplayer)/2)-(Star(cstar).X+1-CamX(countplayer)/2, Star(cstar).Y-CamY(countplayer)/2), scolor 
LINE (Star(cstar).X-CamX(countplayer)/2, Star(cstar).Y+1-CamY(countplayer)/2)-(Star(cstar).X-CamX(countplayer)/2, Star(cstar).Y-1-CamY(countplayer)/2), scolor 
LINE (Star(cstar).X-CamX(countplayer)/2, Star(cstar).Y-CamY(countplayer)/2)-(Star(cstar).X-CamX(countplayer)/2, Star(cstar).Y-CamY(countplayer)/2), scolor+2 

FOR circularmap = 1 TO 8
SELECT CASE circularmap
CASE 1
MapBorder1 = MapBorder
MapBorder2 = 0
CASE 2
MapBorder1 = -MapBorder
MapBorder2 = 0
CASE 3
MapBorder1 = 0
MapBorder2 = MapBorder
CASE 4
MapBorder1 = 0
MapBorder2 = -MapBorder
CASE 5
MapBorder1 = MapBorder
MapBorder2 = MapBorder
CASE 6
MapBorder1 = -MapBorder
MapBorder2 = -MapBorder
CASE 7
MapBorder1 = -MapBorder
MapBorder2 = MapBorder
CASE 8
MapBorder1 = MapBorder
MapBorder2 = -MapBorder
END SELECT
IF ABS(MainShip(countplayer).X - Star(cstar).X-(MapBorder1/2)+CamX(countplayer)/2) < 300 AND ABS(MainShip(countplayer).Y - Star(cstar).Y-(MapBorder2/2)+CamY(countplayer)/2) < 300 THEN
LINE (Star(cstar).X-1+(MapBorder1/2)-CamX(countplayer)/2, Star(cstar).Y+(MapBorder2/2)-CamY(countplayer)/2)-(Star(cstar).X+1+(MapBorder1/2)-CamX(countplayer)/2, Star(cstar).Y+(MapBorder2/2)-CamY(countplayer)/2), scolor 
LINE (Star(cstar).X+(MapBorder1/2)-CamX(countplayer)/2, Star(cstar).Y+1+(MapBorder2/2)-CamY(countplayer)/2)-(Star(cstar).X+(MapBorder1/2)-CamX(countplayer)/2, Star(cstar).Y-1+(MapBorder2/2)-CamY(countplayer)/2), scolor 
LINE (Star(cstar).X+(MapBorder1/2)-CamX(countplayer)/2, Star(cstar).Y+(MapBorder2/2)-CamY(countplayer)/2)-(Star(cstar).X+(MapBorder1/2)-CamX(countplayer)/2, Star(cstar).Y+(MapBorder2/2)-CamY(countplayer)/2), scolor+2
END IF
NEXT circularmap

NEXT cstar
    
END SUB


SUB MoveDrawShips ()

' A specific situation hard coded. Ignore it!
' *******************************************
IF ExtraExplosion > 0 THEN DoBigExplosion
' ********************************************

' By default the current phase is completed.
PhaseDone = TRUE

' In game mode 2(head on head) there is no
' phases and the game ends differently, thus
' never execute the code when PhaseDone is TRUE.
IF GameMode = 2 THEN PhaseDone = FALSE

' Loop through all the ships.
FOR countship = 1 TO numofships

IF Ship(countship).Alive = TRUE THEN

' If any of the ships is alive the
' current phase is NOT completed!
PhaseDone = FALSE

' The the AI for the current ship.
ShipAI countship

skiptoshipdraw:

' The following code keeps the current
' ship within the borders of the map.
IF Ship(countship).Y<0 THEN Ship(countship).Y = MapBorder
IF Ship(countship).Y>MapBorder THEN Ship(countship).Y = 0
IF Ship(countship).X<0 THEN Ship(countship).X = MapBorder
IF Ship(countship).X>MapBorder THEN Ship(countship).X = 0

' The next lines draw the ship if it's in
' vicinity of the current player's ship.
' The enemy ships need to be drawn over
' the edge of the map to enable the
' circular map effect. Like if the enemy 
' ship is near the bottom of the map it
' needs to be seen to the player that
' is near the top of the map where he
' can pass on the other side of it(the
' bottom of the map). 8 sectors around
' the main drawing section need to
' be checked(up-left, up, up-right, right,
' down-right, down, down-left and left).
IF ABS(MainShip(countplayer).RealX-Ship(countship).X)<400 AND ABS(MainShip(countplayer).RealY-Ship(countship).Y)<400 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer),Ship(countship).Y-CamY(countplayer), @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle

IF MainShip(countplayer).RealX > MapBorder - 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer)+MapBorder,Ship(countship).Y-CamY(countplayer), @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealX < 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer)-MapBorder,Ship(countship).Y-CamY(countplayer), @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealY > MapBorder - 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer),Ship(countship).Y-CamY(countplayer)+MapBorder, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealY < 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer),Ship(countship).Y-CamY(countplayer)-MapBorder, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealX > MapBorder - 300 AND MainShip(countplayer).RealY > MapBorder - 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer)+MapBorder,Ship(countship).Y-CamY(countplayer)+MapBorder, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealX < 300 AND MainShip(countplayer).RealY < 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer)-MapBorder,Ship(countship).Y-CamY(countplayer)-MapBorder, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealX > MapBorder - 300 AND MainShip(countplayer).RealY < 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer)+MapBorder,Ship(countship).Y-CamY(countplayer)-MapBorder, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle
IF MainShip(countplayer).RealY > MapBorder - 300 AND MainShip(countplayer).RealX < 300 THEN AF2.SprBlit_rotate Ship(countship).X-CamX(countplayer)-MapBorder,Ship(countship).Y-CamY(countplayer)+MapBorder, @ShipSprite.p_data[ShipSprite.p_dataindex[Ship(countship).Sprite-1]], Ship(countship).Angle

END IF

NEXT countship

END SUB

SUB ShipAI (currentship)

' This IF represents an exception for the stage 5.
' When the module is destroyed don't use the AI
' (prevents the enemy ships to shoot at you while
' the big explosion is happening).
IF Stage = 5 AND Ship(1).Alive = FALSE THEN EXIT SUB

' By default, the angle between the player's ship
' and the enemy is checked according to REAL
' player's ship coordinates.
IF numofplayers = 1 THEN
MainShipCheckX = MainShip(1).RealX+10
MainShipCheckY = MainShip(1).RealY+8
END IF

' Circular map position fix. For example, if you
' are near the top edge of the map(Y = 2980) and
' the enemy ship is near the bottom edge of the
' map(Y = 20) the enemy ship must behave like the
' player's ship is just south from him with Y
' distance of 40 pixels and not north from it with
' 2960 pixels away!).
' In case the ship is on the edge of the map
' from one side and the enemy ship is on
' the edge from other side modify the player's
' check position variable according to which 
' the angle will be calculated.
IF MainShip(countplayer).RealX > MapBorder - 400 AND Ship(currentship).X < 400 THEN MainShipCheckX = MainShip(countplayer).RealX+10 - MapBorder
IF MainShip(countplayer).RealX < 400 AND Ship(currentship).X > MapBorder - 400 THEN MainShipCheckX = MainShip(countplayer).RealX+10 + MapBorder
IF MainShip(countplayer).RealY > MapBorder - 400 AND Ship(currentship).Y < 400 THEN MainShipCheckY = MainShip(countplayer).RealY+8 - MapBorder
IF MainShip(countplayer).RealY < 400 AND Ship(currentship).Y > MapBorder - 400 THEN MainShipCheckY = MainShip(countplayer).RealY+8 + MapBorder

' In two players mode the enemy follows the
' ship that is closer to him. If the program
' is going through this sub when the first
' player is checked(countplayer = 1) and 
' while the second one is closer to the current
' enemy the AI is skipped for that enemy).
' Note the IFs with "distance1 >= distance2"
' and "distance1 < distance2".
IF numofplayers = 2 THEN
MainShipCheckX1 = MainShip(1).RealX
MainShipCheckY1 = MainShip(1).RealY
IF MainShip(1).RealX > MapBorder - 400 AND Ship(currentship).X < 400 THEN MainShipCheckX1 = MainShip(1).RealX - MapBorder
IF MainShip(1).RealX < 400 AND Ship(currentship).X > MapBorder - 400 THEN MainShipCheckX1 = MainShip(1).RealX + MapBorder
IF MainShip(1).RealY > MapBorder - 400 AND Ship(currentship).Y < 400 THEN MainShipCheckY1 = MainShip(1).RealY - MapBorder
IF MainShip(1).RealY < 400 AND Ship(currentship).Y > MapBorder - 400 THEN MainShipCheckY1 = MainShip(1).RealY + MapBorder

MainShipCheckX2 = MainShip(2).RealX
MainShipCheckY2 = MainShip(2).RealY
IF MainShip(2).RealX > MapBorder - 400 AND Ship(currentship).X < 400 THEN MainShipCheckX2 = MainShip(2).RealX - MapBorder
IF MainShip(2).RealX < 400 AND Ship(currentship).X > MapBorder - 400 THEN MainShipCheckX2 = MainShip(2).RealX + MapBorder
IF MainShip(2).RealY > MapBorder - 400 AND Ship(currentship).Y < 400 THEN MainShipCheckY2 = MainShip(2).RealY - MapBorder
IF MainShip(2).RealY < 400 AND Ship(currentship).Y > MapBorder - 400 THEN MainShipCheckY2 = MainShip(2).RealY + MapBorder

mship1_to_enemyx = ABS(Ship(currentship).X-MainShipCheckX1)
mship1_to_enemyy = ABS(Ship(currentship).Y-MainShipCheckY1)
mship2_to_enemyx = ABS(Ship(currentship).X-MainShipCheckX2)
mship2_to_enemyy = ABS(Ship(currentship).Y-MainShipCheckY2)
distance1 = SQR(mship1_to_enemyx^2+mship1_to_enemyy^2)
distance2 = SQR(mship2_to_enemyx^2+mship2_to_enemyy^2)
IF (distance1 >= distance2 AND MainShip(2).Alive = TRUE) OR MainShip(1).Alive = FALSE THEN
MainShipCheckX = MainShipCheckX2+10  ' The current enemy is closer
MainShipCheckY = MainShipCheckY2+8   ' to the second player.
IF countplayer = 1 AND MainShip(2).Alive = TRUE THEN EXIT SUB  
END IF
IF (distance1 < distance2 AND MainShip(1).Alive = TRUE) OR MainShip(2).Alive = FALSE THEN
MainShipCheckX = MainShipCheckX1+10
MainShipCheckY = MainShipCheckY1+8
IF countplayer = 2 AND MainShip(1).Alive = TRUE THEN EXIT SUB
END IF
IF MainShip(1).Alive = FALSE AND MainShip(2).Alive = FALSE THEN
MainShipCheckY = MainShipCheckX1+10
MainShipCheckX = MainShipCheckY1+8
IF countplayer = 2 THEN EXIT SUB
END IF
END IF

' Exception for the AI of the boss ship in stage 5!
' If got too far away from the module track the
' module and not the player's ship!
IF Ship(currentship).AIMode = 9 AND Ship(currentship).AISubMode = 2 THEN
MainShipCheckX = Ship(1).X
MainShipCheckY = Ship(1).Y
END IF

' Calculate the angle between the current ship and
' the player's ship. 0 angle in rotation routine
' is vertically from down toward up and positive 
' clockwise, thus ATN(delta_x/delta_y).
IF MainShipCheckY-Ship(currentship).Y<>0 THEN shipradangle! = ATN((MainShipCheckX-Ship(currentship).X)/(MainShipCheckY-Ship(currentship).Y))
 
' Turn this angle in degrees.
shipangle! = (shipradangle!* 180)/3.14159

' Adjust the angle to span correctly from
' 0 to 360. This was done in an example program
' and tweeked there. ATN function alone is
' not enough so these corrections are needed!
' **********************************************
IF MainShipCheckY-Ship(currentship).Y = 0 THEN
IF MainShipCheckX<Ship(currentship).X THEN shipangle! = 270
IF MainShipCheckX>Ship(currentship).X THEN shipangle! = 90
END IF
IF MainShipCheckX > Ship(currentship).X THEN
IF MainShipCheckY < Ship(currentship).Y THEN shipangle! = shipangle!*-1
IF MainShipCheckY > Ship(currentship).Y THEN shipangle! = 180-shipangle!
END IF
IF MainShipCheckX < Ship(currentship).X THEN 
IF MainShipCheckY < Ship(currentship).Y THEN shipangle! = 360 - shipangle!
IF MainShipCheckY > Ship(currentship).Y THEN shipangle! = 180 - shipangle!
END IF
IF shipangle! < 0 THEN shipangle! = 270
IF shipangle! = 0 AND MainShipCheckY > Ship(currentship).X THEN shipangle!=180
' *********************************************

' Keep the ship angle between 0 and 360 degrees.
IF shipangle! < 0 THEN shipangle! = shipangle! + 360
IF shipangle! > 359 THEN shipangle! = shipangle! - 360

' According to the position of the player's ship 
' and the angle of the current enemy ship flag the
' proper quadrants so that the AI can rotate the
' ship toward or away from the player's ship
' using the shortest path(angle).
quadrant = 1
IF shipangle!>=0 AND shipangle!<90 THEN quadrant = 1
IF shipangle!>=90 AND shipangle!<180 THEN quadrant = 2
IF shipangle!>=180 AND shipangle!<270 THEN quadrant = 3
IF shipangle!>=270 AND shipangle!<360 THEN quadrant = 4
rquadrant = 1
IF Ship(currentship).Angle>=0 AND Ship(currentship).Angle<90 THEN rquadrant = 1
IF Ship(currentship).Angle>=90 AND Ship(currentship).Angle<180 THEN rquadrant = 2
IF Ship(currentship).Angle>=180 AND Ship(currentship).Angle<270 THEN rquadrant = 3
IF Ship(currentship).Angle>=270 AND Ship(currentship).Angle<360 THEN rquadrant = 4

delta_angle1 = Ship(currentship).Angle 
delta_angle2 = shipangle!
IF delta_angle1<90 AND delta_angle2>270 THEN delta_angle1 = delta_angle1 + 360
IF delta_angle2<90 AND delta_angle1>270 THEN delta_angle2 = delta_angle2 + 360
delta_angle = ABS(delta_angle1-delta_angle2)

Ship(currentship).Reload = Ship(currentship).Reload - 1
IF Ship(currentship).Reload < 0 THEN Ship(currentship).Reload = 0

' Turn the ship's rotation angle into radians
' since we are going to use it with SIN
' COS functions.
radsangle! = (Ship(currentship).Angle* 3.14159)/180

movmode = 1 ' in this default mode the enemy ship always turns 
            ' towards the player's ship

MoveShip = FALSE ' by default don't move the ship

ShipSpeed = Ship(currentship).Speed

' In the player is dead don't allow the
' enemies to shoot(gives a better effect
' when the player gets destroyed and the
' "Game Over" message appears).
IF MainShip(countplayer).Alive = FALSE THEN
MoveShip = TRUE
GOTO skipaimodes:
END IF

' In game mode 2(head on head) when one of the
' players is dead don't allow the enemies to
' shoot.
IF GameMode = 2 THEN
IF MainShip(1).Alive = FALSE OR MainShip(2).Alive = FALSE THEN GOTO skipaimodes:
END IF

' For each AI mode we define the ship's behavior 
' and sub behavior according to the sub AI mode
' (attacking the player's ship or moving
' away from it to prepare for another attack).
' Some AIModes are very similar and they probably
' could have been cramped into lesser number of
' modes but why? Really? To save 1 KB tops 
' of memory?

' If ship AIMode is 1...
IF Ship(currentship).AIMode = 1 THEN
    
' If the ship's AIMode is 1 and AISubMode is 1 too
' then aproach toward the player's ship if the
' player's ship is less than 400 pixels away.
' When the distance becomes less than 100 pixels
' away shoot!
' Ship's type 1 and 2 use this AI mode so few
' extra IF statements were used for this specific
' AI mode.
IF Ship(currentship).AISubMode = 1 AND ABS(MainShipCheckX-Ship(currentship).X)<300 AND ABS(MainShipCheckY-Ship(currentship).Y)<300 THEN 
MoveShip = TRUE
movmode = 1
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<100 AND ABS(MainShipCheckY-Ship(currentship).Y)<100 THEN 
Ship(currentship).Reload = 15
IF Ship(currentship).Typ = 2 THEN Ship(currentship).Reload = 20
IF Ship(currentship).Typ = 1 THEN 
InitiateProjectile Ship(currentship).X+(3*SIN(radsangle!)), Ship(currentship).Y-(3*COS(radsangle!)), 3, Ship(currentship).Angle, INT(Ship(currentship).Speed), 35, Ship(currentship).WeaponPower
playsample (sample(4))
END IF
IF Ship(currentship).Typ = 2 THEN
playsample (sample(4))
InitiateProjectile Ship(currentship).X+(5*COS(radsangle!)), Ship(currentship).Y+(5*SIN(radsangle!)), 4, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(5*COS(radsangle!)), Ship(currentship).Y-(5*SIN(radsangle!)), 4, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
IF Ship(currentship).Typ = 12 THEN
playsample (sample(4))
InitiateProjectile Ship(currentship).X+(5*COS(radsangle!)), Ship(currentship).Y+(5*SIN(radsangle!)), 14, Ship(currentship).Angle, INT(Ship(currentship).Speed), 43, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(5*COS(radsangle!)), Ship(currentship).Y-(5*SIN(radsangle!)), 14, Ship(currentship).Angle, INT(Ship(currentship).Speed), 43, Ship(currentship).WeaponPower
END IF
END IF
' If the enemy ship gets too close to the player's
' ship change the AISubMode to 2(run away).
IF ABS(MainShipCheckX-Ship(currentship).X)<50 AND ABS(MainShipCheckY-Ship(currentship).Y)<50 THEN Ship(currentship).AISubMode = 2
END IF ' End of IF AISubMode = 1

IF Ship(currentship).AISubMode = 2 THEN
' The next IF statement is used with type 2
' of enemy ships which tells him to shoot at
' you if you fly over it while it's running
' away from you. Smart thing.
IF Ship(currentship).Reload = 0 AND Ship(currentship).Typ = 2 AND delta_angle<50 THEN
playsample (sample(4))
InitiateProjectile Ship(currentship).X+(5*COS(radsangle!)), Ship(currentship).Y+(5*SIN(radsangle!)), 4, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(5*COS(radsangle!)), Ship(currentship).Y-(5*SIN(radsangle!)), 4, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
Ship(currentship).Reload = 20
END IF
IF Ship(currentship).Reload = 0 AND Ship(currentship).Typ = 12 AND delta_angle<50 THEN
playsample (sample(4))
InitiateProjectile Ship(currentship).X+(5*COS(radsangle!)), Ship(currentship).Y+(5*SIN(radsangle!)), 14, Ship(currentship).Angle, INT(Ship(currentship).Speed), 43, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(5*COS(radsangle!)), Ship(currentship).Y-(5*SIN(radsangle!)), 14, Ship(currentship).Angle, INT(Ship(currentship).Speed), 43, Ship(currentship).WeaponPower
Ship(currentship).Reload = 12
END IF
' These two variables flag, by order, for ship
' to steer away from the player's ship and to
' move(use engines).
movmode = -1
MoveShip = TRUE
' If the enemy ship moves away enough we tell him to
' get back to AISubMode = 1(attack!).
IF ABS(MainShipCheckX-Ship(currentship).X)>120 OR ABS(MainShipCheckY-Ship(currentship).Y)>120 THEN Ship(currentship).AISubMode = 1
END IF

END IF ' End of IF AIMode = 1

' *************************************************
' If ship AIMode is 2...
IF Ship(currentship).AIMode = 2 THEN

IF Ship(currentship).AISubMode = 1 AND ABS(MainShipCheckX-Ship(currentship).X)<400 AND ABS(MainShipCheckY-Ship(currentship).Y)<400 THEN 
MoveShip = TRUE
movmode = 1
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<100 AND ABS(MainShipCheckY-Ship(currentship).Y)<100 THEN 
Ship(currentship).Reload = 12
IF Ship(currentship).Typ = 3 THEN InitiateProjectile Ship(currentship).X+(6*SIN(radsangle!)), Ship(currentship).Y-(6*COS(radsangle!)), 5, Ship(currentship).Angle, INT(Ship(currentship).Speed), 30, Ship(currentship).WeaponPower
IF Ship(currentship).Typ = 5 THEN 
InitiateProjectile Ship(currentship).X+(6*COS(radsangle!)), Ship(currentship).Y+(6*SIN(radsangle!)), 7, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(6*COS(radsangle!)), Ship(currentship).Y-(6*SIN(radsangle!)), 7, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
playsample (sample(5))
END IF
IF ABS(MainShipCheckX-Ship(currentship).X)<50 AND ABS(MainShipCheckY-Ship(currentship).Y)<50 THEN Ship(currentship).AISubMode = 2
END IF ' End of IF AISubMode = 1

IF Ship(currentship).AISubMode = 2 THEN
IF Ship(currentship).Reload = 0 AND Ship(currentship).Typ = 2 AND delta_angle<50 THEN
Ship(currentship).Reload = 12
IF Ship(currentship).Typ = 3 THEN InitiateProjectile Ship(currentship).X+(6*SIN(radsangle!)), Ship(currentship).Y-(6*COS(radsangle!)), 5, Ship(currentship).Angle, INT(Ship(currentship).Speed), 30, Ship(currentship).WeaponPower
IF Ship(currentship).Typ = 5 THEN 
InitiateProjectile Ship(currentship).X+(6*COS(radsangle!)), Ship(currentship).Y+(6*SIN(radsangle!)), 7, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(6*COS(radsangle!)), Ship(currentship).Y-(6*SIN(radsangle!)), 7, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
playsample (sample(5))
END IF
movmode = -1
MoveShip = TRUE
IF ABS(MainShipCheckX-Ship(currentship).X)>100 OR ABS(MainShipCheckY-Ship(currentship).Y)>100 THEN Ship(currentship).AISubMode = 1
END IF ' End of IF AISubMode = 2

END IF ' End of IF AIMode = 2
' *************************************************

' *************************************************
' If ship AIMode is 3...
IF Ship(currentship).AIMode = 3 THEN
movmode = 1
IF ABS(MainShipCheckX-Ship(currentship).X)<600 AND ABS(MainShipCheckY-Ship(currentship).Y)<600 THEN 
MoveShip = TRUE
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<120 AND ABS(MainShipCheckY-Ship(currentship).Y)<120 AND delta_angle<40 THEN 
Ship(currentship).Reload = 20
InitiateProjectile Ship(currentship).X+(21*SIN(radsangle!)), Ship(currentship).Y-(21*COS(radsangle!)), 6, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
END IF
END IF ' End of IF AIMode = 3
' *************************************************

' *************************************************
' If ship AIMode is 4...
IF Ship(currentship).AIMode = 4 THEN
MoveShip = FALSE
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<110 AND ABS(MainShipCheckY-Ship(currentship).Y)<110 THEN 
Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
Ship(currentship).Reload = 15
InitiateProjectile Ship(currentship).X+(16*SIN(radsangle!)), Ship(currentship).Y-(16*COS(radsangle!)), 8, Ship(currentship).Angle, INT(Ship(currentship).Speed), 50, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(16*SIN(radsangle!)), Ship(currentship).Y+(16*COS(radsangle!)), 8, Ship(currentship).Angle+180, INT(Ship(currentship).Speed), 50, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X+(16*COS(radsangle!)), Ship(currentship).Y+(16*SIN(radsangle!)), 8, Ship(currentship).Angle+90, INT(Ship(currentship).Speed), 50, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(16*COS(radsangle!)), Ship(currentship).Y-(16*SIN(radsangle!)), 8, Ship(currentship).Angle-90, INT(Ship(currentship).Speed), 50, Ship(currentship).WeaponPower
playsample (sample(7))
GOTO skipairotation:
END IF
END IF ' End of IF AIMode = 4
' *************************************************

' *************************************************
' If ship AIMode is 5...
IF Ship(currentship).AIMode = 5 THEN
IF ABS(MainShipCheckX-Ship(currentship).X)<400 AND ABS(MainShipCheckY-Ship(currentship).Y)<400 THEN 
MoveShip = TRUE
movmode = 1
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<130 AND ABS(MainShipCheckY-Ship(currentship).Y)<130 THEN 
Ship(currentship).Reload = 130
InitiateProjectile Ship(currentship).X+(16*SIN(radsangle!)), Ship(currentship).Y-(16*COS(radsangle!)), 9, Ship(currentship).Angle, INT(Ship(currentship).Speed), 200, Ship(currentship).WeaponPower
END IF
END IF
END IF ' End of IF AIMode = 5
' *************************************************

' *************************************************
' If ship AIMode is 6...
IF Ship(currentship).AIMode = 6 THEN
IF Ship(currentship).AISubMode = 1 AND ABS(MainShipCheckX-Ship(currentship).X)<300 AND ABS(MainShipCheckY-Ship(currentship).Y)<300 THEN 
MoveShip = TRUE
movmode = 1
' Slow down when near the player's ship!
IF ABS(MainShipCheckX-Ship(currentship).X)<110 AND ABS(MainShipCheckY-Ship(currentship).Y)<110 THEN ShipSpeed = Ship(currentship).Speed/2
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<120 AND ABS(MainShipCheckY-Ship(currentship).Y)<120 THEN
Ship(currentship).Reload = 12 
InitiateProjectile Ship(currentship).X+(3*SIN(radsangle!)), Ship(currentship).Y-(3*COS(radsangle!)), 10, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
IF ABS(MainShipCheckX-Ship(currentship).X)<50 AND ABS(MainShipCheckY-Ship(currentship).Y)<50 THEN Ship(currentship).AISubMode = 2
END IF ' End of IF AISubMode = 1

IF Ship(currentship).AISubMode = 2 THEN
ShipSpeed = Ship(currentship).Speed
movmode = -1
MoveShip = TRUE
IF ABS(MainShipCheckX-Ship(currentship).X)>200 OR ABS(MainShipCheckY-Ship(currentship).Y)>200 THEN Ship(currentship).AISubMode = 1
END IF

END IF ' End of IF AIMode = 6
' ************************************************

' *************************************************
' If ship AIMode is 7...
IF Ship(currentship).AIMode = 7 THEN
IF Ship(currentship).AISubMode = 1 AND ABS(MainShipCheckX-Ship(currentship).X)<500 AND ABS(MainShipCheckY-Ship(currentship).Y)<500 THEN 
MoveShip = TRUE
movmode = 1
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<100 AND ABS(MainShipCheckY-Ship(currentship).Y)<100 THEN
Ship(currentship).Reload = 12 
InitiateProjectile Ship(currentship).X-(5*SIN(radsangle!)), Ship(currentship).Y+(5*COS(radsangle!)), 11, Ship(currentship).Angle-180, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
IF ABS(MainShipCheckX-Ship(currentship).X)<50 AND ABS(MainShipCheckY-Ship(currentship).Y)<50 THEN Ship(currentship).AISubMode = 2
END IF ' End of IF AISubMode = 1

IF Ship(currentship).AISubMode = 2 THEN
movmode = -1
MoveShip = TRUE
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<90 AND ABS(MainShipCheckY-Ship(currentship).Y)<90 AND delta_angle>120 THEN
Ship(currentship).Reload = 12 
InitiateProjectile Ship(currentship).X-(5*SIN(radsangle!)), Ship(currentship).Y+(5*COS(radsangle!)), 11, Ship(currentship).Angle-180, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
END IF
IF ABS(MainShipCheckX-Ship(currentship).X)>200 OR ABS(MainShipCheckY-Ship(currentship).Y)>200 THEN Ship(currentship).AISubMode = 1
END IF

END IF ' End of IF AIMode = 7
' ************************************************

' *************************************************
' If ship AIMode is 8...
IF Ship(currentship).AIMode = 8 THEN
IF Ship(currentship).AISubMode = 1 AND ABS(MainShipCheckX-Ship(currentship).X)<500 AND ABS(MainShipCheckY-Ship(currentship).Y)<500 THEN 
MoveShip = TRUE
movmode = 1
' Slow down when near the player's ship!
IF ABS(MainShipCheckX-Ship(currentship).X)<110 AND ABS(MainShipCheckY-Ship(currentship).Y)<110 THEN ShipSpeed = Ship(currentship).Speed/2
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<120 AND ABS(MainShipCheckY-Ship(currentship).Y)<120 THEN
Ship(currentship).Reload = 16 
InitiateProjectile Ship(currentship).X+(13*COS(radsangle!)), Ship(currentship).Y+(13*SIN(radsangle!)), 12, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(13*COS(radsangle!)), Ship(currentship).Y-(13*SIN(radsangle!)), 12, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X+(13*SIN(radsangle!)), Ship(currentship).Y-(13*COS(radsangle!)), 5, Ship(currentship).Angle, INT(Ship(currentship).Speed), 30, Ship(currentship).WeaponPower-1
playsample (sample(5))
END IF
IF ABS(MainShipCheckX-Ship(currentship).X)<60 AND ABS(MainShipCheckY-Ship(currentship).Y)<60 THEN Ship(currentship).AISubMode = 2
END IF ' End of IF AISubMode = 1

IF Ship(currentship).AISubMode = 2 THEN
ShipSpeed = Ship(currentship).Speed
movmode = -1
MoveShip = TRUE
IF ABS(MainShipCheckX-Ship(currentship).X)>100 OR ABS(MainShipCheckY-Ship(currentship).Y)>100 THEN Ship(currentship).AISubMode = 1
END IF

END IF ' End of IF AIMode = 8
' ************************************************

' *************************************************
' If ship AIMode is 9(boss ship; note the spawnship part!)...
IF Ship(currentship).AIMode = 9 THEN

IF Ship(currentship).AISubMode = 1 AND ABS(MainShipCheckX-Ship(currentship).X)<200 AND ABS(MainShipCheckY-Ship(currentship).Y)<200 THEN 
IF Frame6 = 10 AND Ship(currentship).WeaponLevel>0 THEN 
SpawnShip Ship(currentship).X+(10*SIN(radsangle!)), Ship(currentship).Y-(10*COS(radsangle!)), 12, Ship(currentship).Angle
Ship(currentship).WeaponLevel = Ship(currentship).WeaponLevel -1
END IF
MoveShip = TRUE
movmode = 1
IF Ship(currentship).Reload = 0 AND ABS(MainShipCheckX-Ship(currentship).X)<130 AND ABS(MainShipCheckY-Ship(currentship).Y)<130 THEN 
Ship(currentship).Reload = 18
InitiateProjectile Ship(currentship).X+(20*COS(radsangle!))+(30*SIN(radsangle!)), Ship(currentship).Y+(20*SIN(radsangle!))-(30*COS(radsangle!)), 13, Ship(currentship).Angle, INT(Ship(currentship).Speed), 45, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(20*COS(radsangle!))+(30*SIN(radsangle!)), Ship(currentship).Y-(20*SIN(radsangle!))-(30*COS(radsangle!)), 13, Ship(currentship).Angle, INT(Ship(currentship).Speed), 45, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X+(35*SIN(radsangle!)), Ship(currentship).Y-(35*COS(radsangle!)), 5, Ship(currentship).Angle, INT(Ship(currentship).Speed), 45, Ship(currentship).WeaponPower - 1
playsample (sample(5))
END IF
IF ABS(Ship(1).X-Ship(currentship).X)>200 OR ABS(Ship(1).Y-Ship(currentship).Y)>200 THEN Ship(currentship).AISubMode = 2
END IF ' End of IF AISubMode = 1

IF Ship(currentship).AISubMode = 2 THEN
IF Frame6 = 10 AND Ship(currentship).WeaponLevel>0 THEN 
SpawnShip Ship(currentship).X+(10*SIN(radsangle!)), Ship(currentship).Y-(10*COS(radsangle!)), 12, Ship(currentship).Angle
Ship(currentship).WeaponLevel = Ship(currentship).WeaponLevel -1
END IF
IF Ship(currentship).Reload = 0 AND delta_angle<70 THEN
Ship(currentship).Reload = 18
InitiateProjectile Ship(currentship).X+(20*COS(radsangle!))+(30*SIN(radsangle!)), Ship(currentship).Y+(20*SIN(radsangle!))-(30*COS(radsangle!)), 13, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X-(20*COS(radsangle!))+(30*SIN(radsangle!)), Ship(currentship).Y-(20*SIN(radsangle!))-(30*COS(radsangle!)), 13, Ship(currentship).Angle, INT(Ship(currentship).Speed), 40, Ship(currentship).WeaponPower
InitiateProjectile Ship(currentship).X+(35*SIN(radsangle!)), Ship(currentship).Y-(35*COS(radsangle!)), 5, Ship(currentship).Angle, INT(Ship(currentship).Speed), 45, Ship(currentship).WeaponPower - 1
playsample (sample(5))
END IF
ShipSpeed = -Ship(currentship).Speed
movmode = -1
MoveShip = TRUE
IF ABS(Ship(1).X-Ship(currentship).X)<100 AND ABS(Ship(1).Y-Ship(currentship).Y)<100 THEN Ship(currentship).AISubMode = 1
END IF ' End of IF AISubMode = 2

END IF ' End of IF AIMode = 9
' *************************************************

' If ship AIMode is 11...
IF Ship(currentship).AIMode = 11 THEN
MoveShip = FALSE
Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel
GOTO skipairotation:
END IF ' End of IF AIMode = 11
' *************************************************

skipaimodes:

' The next lines control the enemy ship
' rotation according to the targeted
' player's ship. The next 4 lines
' are needed to enable the enemy ships
' to move toward their target using the
' shortest path.
distance_ship_to_0 = Ship(currentship).Angle
distance_ship_to_360 = 360 - Ship(currentship).Angle
distance_target_to_0 = shipangle!
distance_target_to_360 = 360 - shipangle!

IF rquadrant = 1 THEN
IF quadrant = 2 THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF quadrant = 3 THEN 'Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_0+distance_target_to_360)>(shipangle!-Ship(currentship).Angle) THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_0+distance_target_to_360)<(shipangle!-Ship(currentship).Angle) THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
END IF
IF quadrant = 4 THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
END IF
IF rquadrant = 2 THEN
IF quadrant = 1 THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF quadrant = 3 THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF quadrant = 4 THEN 'Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_0+distance_target_to_360)>(shipangle!-Ship(currentship).Angle) THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_0+distance_target_to_360)<(shipangle!-Ship(currentship).Angle) THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
END IF
END IF
IF rquadrant = 3 THEN
IF quadrant = 1 THEN 'Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_360+distance_target_to_0)>(Ship(currentship).Angle-shipangle!) THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_360+distance_target_to_0)<(Ship(currentship).Angle-shipangle!) THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
END IF
IF quadrant = 2 THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF quadrant = 4 THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
END IF
IF rquadrant = 4 THEN
IF quadrant = 1 THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
IF quadrant = 3 THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF quadrant = 2 THEN 'Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_360+distance_target_to_0)>(Ship(currentship).Angle-shipangle!) THEN Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode
IF (distance_ship_to_360+distance_target_to_0)<(Ship(currentship).Angle-shipangle!) THEN Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode
END IF
END IF
IF rquadrant = quadrant THEN
IF shipangle!>Ship(currentship).Angle then Ship(currentship).Angle = Ship(currentship).Angle + Ship(currentship).TurnLevel*movmode 
IF shipangle!<Ship(currentship).Angle then Ship(currentship).Angle = Ship(currentship).Angle - Ship(currentship).TurnLevel*movmode 
END IF

skipairotation:

' Keep the ship's angle between 0 and 360 degrees.
IF Ship(currentship).Angle<0 THEN Ship(currentship).Angle = Ship(currentship).Angle+360
IF Ship(currentship).Angle>359 THEN Ship(currentship).Angle = Ship(currentship).Angle-360
' Convert the final ship's angle into radians.
radsangle! = (Ship(currentship).Angle* 3.14159)/180

IF MoveShip = TRUE THEN
' Move the ship according to his speed and angle.
Ship(currentship).X = Ship(currentship).X + ShipSpeed * SIN(radsangle!)
Ship(currentship).Y = Ship(currentship).Y - ShipSpeed * COS(radsangle!)
END IF

END SUB

SUB InitiateExplosion (ex!, ey!, etyp, eduration)
 
' Loop through the explosions...
FOR initexpl = 1 TO numofexplosions

' If a free one is found initiate it on
' the give position and with the given type.
' eduration is used to flag the amount of
' loops the explosion should last. It
' supposed to be 5 by default by due some
' last minute additions this variable(parameter)
' ended up being used for another 
' purpose so don't be confused.
IF Explosion(initexpl).Locked = FALSE THEN
Explosion(initexpl).Locked = TRUE
Explosion(initexpl).X = ex!
Explosion(initexpl).Y = ey!
Explosion(initexpl).Typ = etyp
Explosion(initexpl).LifeTime = 0

' eduration represents the amount of
' loops explosion should last and it
' has to be 5. Why I'm using these
' other values is to trigger sparkles
' inside this sub since sparkles
' came as a last minute addition and
' modifying this sub on another way
' felt like a drag. Sparkles come out
' of the center of every big explosion,
' going in 4 directons. Very bad coding
' and not really neccesary to be done on 
' this way since the rotation of the 
' sparkles around the big explosion is 
' barely visible. But I don't care!

' I player 2 is exploding spawn sparkles
' rotated by player's 2 angle and
' reset eduration on the proper value.
IF eduration = 3 THEN
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(2).Angle+45, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(2).Angle+135, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(2).Angle+225, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(2).Angle+315, 1
eduraton = 5
END IF
' I player 1 is exploding spawn sparkles
' rotated by player's 1 angle.
IF eduration = 4 THEN
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(1).Angle+45, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(1).Angle+135, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(1).Angle+225, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, MainShip(1).Angle+315, 1
eduraton = 5
END IF
' If any random enemy ship is exploding
' spawn 4 sparkles for each explosion.
IF eduration = 6 THEN
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(hitship).Angle+45, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(hitship).Angle+135, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(hitship).Angle+225, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(hitship).Angle+315, 1
eduraton = 5
END IF
' If the big boss ship is
' exploding spawn sparkles for
' each explosion(the big boss
' explosion is done separately
' so I can't use Ship(hitship)
' for the angle.
IF eduration = 7 THEN
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(2).Angle+45, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(2).Angle+135, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(2).Angle+225, 1
InitiateSparkle Explosion(initexpl).X+10, Explosion(initexpl).Y+10, Ship(2).Angle+315, 1
eduraton = 5
END IF
' Type 4 explosion("spark ignited") has 3 frames
' so we need to correct eduration to 3 for this
' specific explosion type.
IF Explosion(initexpl).Typ = 4 THEN eduration = 3
' With explosions Shield variable is used as
' the "timeout" variable so don't be confused.
Explosion(initexpl).Shield = eduration
IF Explosion(initexpl).Typ = 1 THEN playsample (sample(2))
IF Explosion(initexpl).Typ = 2 THEN playsample (sample(3))
EXIT SUB
END IF

NEXT initexpl

END SUB

SUB ExplosionLayer ()

' Loop through all the explosions.
FOR countexpl = 1 TO numofexplosions
 
' In two players mode and when the loop is
' going through the second player skip
' explosion managing and go straight to
' drawing.
IF numofplayers = 2 AND countplayer = 2 THEN GOTO skiptoexpldraw:

' Err...these two lines are just about the
' entire explosion "managing".
' LifeTime variable raises toward Shield
' and when it exceeds Shield the explosion
' is removed from drawing(it's flagged as 
' Locked = TRUE).
IF Explosion(countexpl).Locked = TRUE THEN Explosion(countexpl).LifeTime = Explosion(countexpl).LifeTime + 1
IF Explosion(countexpl).LifeTime > Explosion(countexpl).Shield THEN Explosion(countexpl).Locked = FALSE

skiptoexpldraw:

' Skip drawing if the explosion is not activated.
' It's active if it's flagged as Locked = TRUE,
' meaning not available for initiation in the
' InitiateExplosion sub(we mustn't initiate an
' active explosion).
IF Explosion(countexpl).Locked = FALSE THEN goto skiptonextexpl:

' According to explosion type flag the proper
' explosion sprite.
IF Explosion(countexpl).Typ = 1 THEN explspr = Explosion(countexpl).LifeTime
IF Explosion(countexpl).Typ = 2 THEN explspr = Explosion(countexpl).LifeTime+10
IF Explosion(countexpl).Typ = 3 THEN explspr = Explosion(countexpl).LifeTime+5
IF Explosion(countexpl).Typ = 4 THEN explspr = Explosion(countexpl).LifeTime+15

IF explspr = 0 THEN explspr = 1 ' A precaution measure
IF Explosion(countexpl).LifeTime>0 AND explspr<19 THEN AF2.SprBlit Explosion(countexpl).X-CamX(countplayer),Explosion(countexpl).Y-CamY(countplayer), @Sprites2.p_data[Sprites2.p_dataindex[explspr-1]], GFX_v, GFX_h

' The usual, "go around the
' main map sector and draw
' the explosions in those 
' sectors too" loop. Uh-oh.
FOR circularmap = 1 TO 8
SELECT CASE circularmap
CASE 1
MapBorder1 = MapBorder
MapBorder2 = 0
CASE 2
MapBorder1 = -MapBorder
MapBorder2 = 0
CASE 3
MapBorder1 = 0
MapBorder2 = MapBorder
CASE 4
MapBorder1 = 0
MapBorder2 = -MapBorder
CASE 5
MapBorder1 = MapBorder
MapBorder2 = MapBorder
CASE 6
MapBorder1 = -MapBorder
MapBorder2 = -MapBorder
CASE 7
MapBorder1 = -MapBorder
MapBorder2 = MapBorder
CASE 8
MapBorder1 = MapBorder
MapBorder2 = -MapBorder
END SELECT
IF explspr = 0 THEN explspr = 1 ' A precaution measure
IF Explosion(countexpl).LifeTime>0 AND explspr<19 THEN AF2.SprBlit Explosion(countexpl).X-CamX(countplayer)+MapBorder1,Explosion(countexpl).Y-CamY(countplayer)+MapBorder2, @Sprites2.p_data[Sprites2.p_dataindex[explspr-1]], GFX_v, GFX_h
NEXT circularmap

skiptonextexpl:
NEXT countexpl
    
END SUB

Sub setSoundVolume
IF PlaySound = TRUE THEN
IF SFXVolume = 0 THEN SetVol% = 0
IF SFXVolume = 1 THEN SetVol% = 63
IF SFXVolume = 2 THEN SetVol% = 126
IF SFXVolume = 3 THEN SetVol% = 190
IF SFXVolume = 4 THEN SetVol% = 255
FSOUND_SetSFXMasterVolume(SetVol%)
IF MusicVolume = 0 THEN SetVol% = 0
IF MusicVolume = 1 THEN SetVol% = 63
IF MusicVolume = 2 THEN SetVol% = 126
IF MusicVolume = 3 THEN SetVol% = 190
IF MusicVolume = 4 THEN SetVol% = 255
FSOUND_SetVolumeAbsolute(1, SetVol%)
END IF
End Sub

sub playsample(plsnd as integer ptr)
    IF SFXVolume = 0 THEN EXIT SUB
    If PlaySound = TRUE Then 
        'setSoundVolume
        FSOUND_PlaySound(FSOUND_FREE, plsnd)
        setSoundVolume
    end if
end sub

Sub playStreamMusic(musc As String)
    IF MusicVolume = 0 THEN EXIT SUB
    if PlaySound = TRUE then
        music_handle = FSOUND_Stream_Open(musc, FSOUND_LOOP_NORMAL, 0, 0 ) 
        FSOUND_Stream_SetMode(music_handle,FSOUND_LOOP_NORMAL) 
        FSOUND_Stream_Play(1, music_handle)
IF MusicVolume = 0 THEN SetVol% = 0
IF MusicVolume = 1 THEN SetVol% = 63
IF MusicVolume = 2 THEN SetVol% = 126
IF MusicVolume = 3 THEN SetVol% = 190
IF MusicVolume = 4 THEN SetVol% = 255
FSOUND_SetVolumeAbsolute(1, SetVol%)
end if	
end sub

Sub stopStreamMusic()
    if PlaySound = TRUE then
        FSOUND_Stream_Stop music_handle
        FSOUND_Stream_Close music_handle
    end if
end sub

SUB DrawMiniMap ()

' A sub that draws the mini map. Very ugly
' and I came to the final version through
' many nitpicks and adjustions.

LINE (550,390)-(640,480), 0, BF

FOR cplanet = 1 TO 8
FOR mapposition = 1 TO 9
SELECT CASE mapposition
CASE 1
minimapx = (Planet(cplanet).X-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y-CamY(countplayer))/38+startminimapy
CASE 2
minimapx = (Planet(cplanet).X-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y-CamY(countplayer))/38+startminimapy
CASE 3
minimapx = (Planet(cplanet).X+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y-CamY(countplayer))/38+startminimapy
CASE 4
minimapx = (Planet(cplanet).X-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y-MapBorder-CamY(countplayer))/38+startminimapy
CASE 5
minimapx = (Planet(cplanet).X-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y+MapBorder-CamY(countplayer))/38+startminimapy
CASE 6
minimapx = (Planet(cplanet).X+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y+MapBorder-CamY(countplayer))/38+startminimapy
CASE 7
minimapx = (Planet(cplanet).X-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y-MapBorder-CamY(countplayer))/38+startminimapy
CASE 8
minimapx = (Planet(cplanet).X-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y+MapBorder-CamY(countplayer))/38+startminimapy
CASE 9
minimapx = (Planet(cplanet).X+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Planet(cplanet).Y-MapBorder-CamY(countplayer))/38+startminimapy    
END SELECT
IF Planet(cplanet).Alive = TRUE AND ABS(591-minimapx)<30 AND ABS(435-minimapy)<30 THEN 
plclr = 143
IF Planet(cplanet).Typ = 10 THEN plclr = 175
IF Planet(cplanet).Typ = 2 or Planet(cplanet).Typ = 9 THEN plclr = 127
PSET (minimapx, minimapy), plclr 
PSET (minimapx+1, minimapy), plclr 
PSET (minimapx+1, minimapy+1), plclr 
PSET (minimapx, minimapy+1), plclr 
END IF
NEXT mappositions
NEXT cplanet

FOR cship = 1 TO numofships
FOR mapposition = 1 TO 9
SELECT CASE mapposition
CASE 1
minimapx = (Ship(cship).X-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y-CamY(countplayer))/38+startminimapy
CASE 2
minimapx = (Ship(cship).X-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y-CamY(countplayer))/38+startminimapy
CASE 3
minimapx = (Ship(cship).X+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y-CamY(countplayer))/38+startminimapy
CASE 4
minimapx = (Ship(cship).X-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y-MapBorder-CamY(countplayer))/38+startminimapy
CASE 5
minimapx = (Ship(cship).X-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y+MapBorder-CamY(countplayer))/38+startminimapy
CASE 6
minimapx = (Ship(cship).X+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y+MapBorder-CamY(countplayer))/38+startminimapy
CASE 7
minimapx = (Ship(cship).X-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y-MapBorder-CamY(countplayer))/38+startminimapy
CASE 8
minimapx = (Ship(cship).X-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y+MapBorder-CamY(countplayer))/38+startminimapy
CASE 9
minimapx = (Ship(cship).X+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (Ship(cship).Y-MapBorder-CamY(countplayer))/38+startminimapy    
END SELECT
IF Ship(cship).Alive = TRUE AND ABS(591-minimapx)<30 AND ABS(435-minimapy)<30 THEN PSET (minimapx, minimapy), 47   
NEXT mappositions
NEXT cship

IF numofplayers = 2 THEN
IF countplayer = 1 THEN otherplayer = 2
IF countplayer = 2 THEN otherplayer = 1
FOR mapposition = 1 TO 9
SELECT CASE mapposition
CASE 1
minimapx = (MainShip(otherplayer).RealX-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY-CamY(countplayer))/38+startminimapy
CASE 2
minimapx = (MainShip(otherplayer).RealX-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY-CamY(countplayer))/38+startminimapy
CASE 3
minimapx = (MainShip(otherplayer).RealX+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY-CamY(countplayer))/38+startminimapy
CASE 4
minimapx = (MainShip(otherplayer).RealX-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY-MapBorder-CamY(countplayer))/38+startminimapy
CASE 5
minimapx = (MainShip(otherplayer).RealX-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY+MapBorder-CamY(countplayer))/38+startminimapy
CASE 6
minimapx = (MainShip(otherplayer).RealX+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY+MapBorder-CamY(countplayer))/38+startminimapy
CASE 7
minimapx = (MainShip(otherplayer).RealX-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY-MapBorder-CamY(countplayer))/38+startminimapy
CASE 8
minimapx = (MainShip(otherplayer).RealX-MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY+MapBorder-CamY(countplayer))/38+startminimapy
CASE 9
minimapx = (MainShip(otherplayer).RealX+MapBorder-CamX(countplayer))/38+startminimapx
minimapy = (MainShip(otherplayer).RealY-MapBorder-CamY(countplayer))/38+startminimapy    
END SELECT
IF countstageend(otherplayer)<131 AND MainShip(otherplayer).Alive = TRUE AND ABS(591-minimapx)<30 AND ABS(435-minimapy)<30 THEN PSET (minimapx, minimapy), 111    
NEXT mappositions
END IF

GET (551,391)-(639,479), MiniMapBuffer(countplayer)

END SUB

SUB MainMenu

' When the program first enters this sub
' flag that the screen should be joined
' (the animation).
ScreenTransition = TRUE

' Starting menu position.
menupos = 1
menustart:
IF menupos = 1 or menupos = 2 THEN playStreamMusic("Sound/atmosphere.mp3")
' optionfade variable is used to fade in/out
' the options when you change them. The
' fade in/out thingie doesn't really give
' the best results.
FOR copt = 1 TO 6
optionfade(copt) = 10
NEXT copt

DO

FPS = FPS + 1                     ' Used to count FPS.
if StartTime& + 1 < timer then
 FPS2 = FPS
 FPS = 0
 seconds = seconds + 1
 StartTime& = timer
end if

Frame2 = (Frame2 MOD 2) + 1

IF PlaySound = TRUE THEN FSOUND_Update

screenset workpage, workpage xor 1

AF2.ClearScreen 0 

DrawStars 1

' Loop through all the options and
' make their brightness value 10.
FOR copt = 1 TO 6
IF menupos<>copt THEN 
IF optionfade(copt)>10 THEN optionfade(copt) = optionfade(copt) - 5
IF optionfade(copt)<10 THEN optionfade(copt) = 10
END IF
' On the option where you currently are
' flag full brightness.
IF menupos=copt THEN
IF optionfade(copt)<42 THEN optionfade(copt) = optionfade(copt) + 5
IF optionfade(copt)>42 THEN optionfade(copt) = 42
END IF
NEXT copt

' Paste the banner.
PUT (0,0), background(1, 0), TRANS
' Paste all the options with their
' brightness(optionfade variable).
AF2.PP256fnt_brightness "START NEW GAME", 103, 140, 0, optionfade(1), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "PLAY HEAD ON HEAD", 103, 150, 0, optionfade(2), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "OPTIONS", 103, 160, 0, optionfade(3), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "TOP SCORES", 103, 170, 0, optionfade(4), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "INSTRUCTIONS", 103, 180, 0, optionfade(5), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "EXIT", 103, 190, 0, optionfade(6), Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240

' Change current option if the user pressed
' up or down.
IF MULTIKEY(SC_UP) AND KeyFree = TRUE THEN 
menupos = menupos - 1
KeyFree = FALSE
IF menupos < 1 THEN menupos = 1
END IF
IF MULTIKEY(SC_DOWN) AND KeyFree = TRUE THEN 
menupos = menupos + 1
KeyFree = FALSE
IF menupos > 6 THEN menupos = 6
END IF
' If the user presses enter execute a task
' according to the current option(start game,
' display top scores, etc.).
IF MULTIKEY(SC_ENTER) AND KeyFree = TRUE THEN
KeyFree = FALSE
SELECT CASE menupos
CASE 1
BreakScreen
ChoosePlayers
BreakScreen
NewGameReset
WHILE MULTIKEY(SC_ENTER)
WEND
Story
MainLoop
menupos = 1
GOTO menustart:
CASE 2
BreakScreen
InitHeadOnHead
MainLoop
menupos = 2
GOTO menustart:
CASE 3
BreakScreen
Options
KeyFree = FALSE
menupos = 3
BreakScreen
goto menustart:
CASE 4
BreakScreen
ReadHighScore
KeyFree = FALSE
goto menustart:
CASE 5
BreakScreen
Instructions
KeyFree = FALSE
goto menustart:
CASE 6
BreakScreen
AF2.RemoveSpr Sprites1
AF2.RemoveSpr Sprites2
AF2.RemoveSpr Sprites3
AF2.RemoveSpr ShipSprite
AF2.RemoveSpr ProjSprite
AF2.RemoveSpr Font1
AF2.RemoveSpr PlanetSprite
AF2.RemoveSpr PickupSprite
IMAGEDESTROY ScreenBuffer(1)
IMAGEDESTROY ScreenBuffer(2)
IMAGEDESTROY MiniMapBuffer(1)
IMAGEDESTROY MiniMapBuffer(2)
IMAGEDESTROY FullScreenBuffer(1)
IMAGEDESTROY FullScreenBuffer(2)
IMAGEDESTROY FullScreenBuffer(3)
FOR cmbuffer = 1 TO 7
IMAGEDESTROY MiscBuffer1(cmbuffer)
NEXT cmbuffer
FOR cmbuffer = 1 TO 9
IMAGEDESTROY MiscBuffer2(cmbuffer)
NEXT cmbuffer
IF PlaySound = TRUE THEN FSOUND_Close
END
END SELECT
END IF

JoinScreen

workpage xor = 1

IF MULTIKEY(SC_F1) THEN
BSAVE "screenshot"+LTRIM$(RTRIM$(STR$(sshot)))+".bmp", 0, 307204
sshot=sshot+1
WHILE MULTIKEY(SC_F1)
WEND
END IF

do 
loop until timer& - st >= (1/65) 
st = timer& 

SLEEP 1 

IF MULTIKEY(SC_ENTER) OR MULTIKEY(SC_UP) OR MULTIKEY(SC_DOWN) THEN GOTO skipkeyrestore:
KeyFree = TRUE
skipkeyrestore:

LOOP 

END SUB

SUB BreakScreen ()

' This sub executes the "break screen"
' animation where one side of it(five lines 
' horizontally, then five lines blank, then 
' five lines horizontally, and so on) scrolls 
' to the left while the other side to the right.
' It's designed to capture the full 640*480
' screen, break it in two parts and scroll
' it apart. ScreenTransition variable is
' used to flag that the screen has been
' broken this way so we can join it 
' in another loop using, of course, a 
' different captured image.
GET (0,0)-(639,479), background(4,0)
FOR cline = 0 TO 96 STEP 2
LINE (0,cline*5)-(640,4+cline*5), 0, BF    
NEXT cline
GET (0,0)-(639,479), background(2,0)
PUT (0,0), background(4, 0), PSET
FOR cline = 1 TO 96 STEP 2
LINE (0,cline*5)-(640,4+cline*5), 0, BF    
NEXT cline
GET (0,0)-(639,479), background(3,0)
ScreenTransition = TRUE
DO
screenset workpage, workpage xor 1
AF2.ClearScreen 0 
xmov = xmov + 10
IF xmov = 80 THEN playsample (sample(10))
IF xmov > 640 THEN xmov = 640
PUT (-xmov, 0), background(2,0), TRANS
PUT (xmov,0), background(3,0), TRANS
workpage xor = 1 
do 
loop until timer& - st >= (1/85) 
st = timer& 
SLEEP 1
LOOP UNTIL xmov = 640

END SUB

SUB JoinScreen ()
 
' A sub that joing the "broken" screen
' into a new one but only if it has
' been previously "broken"(note the
' ScreenTransition variable).
IF ScreenTransition = TRUE THEN
ScreenTransition = FALSE 
GET (0,0)-(639,479), background(4,0)
FOR cline = 0 TO 96 STEP 2
LINE (0,cline*5)-(640,4+cline*5), 0, BF    
NEXT cline
GET (0,0)-(639,479), background(2,0)
PUT (0,0), background(4, 0), PSET
FOR cline = 1 TO 96 STEP 2
LINE (0,cline*5)-(640,4+cline*5), 0, BF    
NEXT cline
GET (0,0)-(639,479), background(3,0)
xmov = 640
AF2.ClearScreen 0 
DO
screenset workpage, workpage xor 1
AF2.ClearScreen 0 
xmov = xmov - 10
IF xmov < 0 THEN xmov = 0
IF xmov = 580 THEN playsample (sample(10))
PUT (-xmov, 0), background(2,0), TRANS
PUT (xmov,0), background(3,0), TRANS
workpage xor = 1 
do 
loop until timer& - st >= (1/85) 
st = timer& 
SLEEP 1
LOOP UNTIL xmov = 0
END IF
    
END SUB

Sub NewGameReset

' Init starting stage and proper game mode.
Stage = 1
GameMode = 1
PlayingAgain = FALSE
warningmsg(1) = FALSE
warningmsg(2) = FALSE

' startplayers variable is only used 
' with score inputting. In case one
' of the players dies before score
' inputting I need to store the 
' information about how many players
' started the game to avoid this 
' conflict.
startplayers = numofplayers
' Another variable used with scores
' to solve the mentioned conflict.
scoreflag = 0
Player1OriginalScore = 0

' Set proper ship sprites.
MainShip(1).StartSprite = 2
MainShip(2).StartSprite = 6

' Loop through the players and set
' their starting characteristics.
FOR countplayer = 1 TO numofplayers
    
MainShip(countplayer).Alive = TRUE
MainShip(countplayer).Shield = 35
MainShip(countplayer).Score = 0
MainShip(countplayer).Shots = 0
MainShip(countplayer).ShipProj = countplayer

MainShip(countplayer).MaxShield = 35 'higher better(2 more levels)
MainShip(countplayer).MaxReverse = 1.4   ' higher better(connected with acceleration)
MainShip(countplayer).Acceleration = 0.2 ' higher better(2 more levels)
MainShip(countplayer).MaxBattery = 10 ' higher better(balance)
MainShip(countplayer).WeaponLevel = 1 ' highest(the best) is 4
MainShip(countplayer).TurnLevel = 8 'lowest(the best) possible is 4

MainShip(countplayer).Battery = 0
MainShip(countplayer).Speed = 0
MainShip(countplayer).Sprite = MainShip(countplayer).StartSprite
MainShip(countplayer).WeaponPower = 1
MainShip(countplayer).Energy = 0

MainShip(countplayer).X = 310
MainShip(countplayer).Y = 232

MainShip(countplayer).Angle = 0

NEXT countplayer

' Init first stage variables.
InitStage

END SUB

SUB InitStage

' Init phase 1.
PhaseNumber = 1
' Reset death and stage end
' control variables.
countplayerdeath(1) = 0
countplayerdeath(2) = 0
countstageend(1) = 0
countstageend(2) = 0
CountStartStage = 60
seconds = 0
PhaseDone = FALSE

' Reset the explosions and projectiles.
FOR rexpl = 1 TO numofexplosions
Explosion(rexpl).Locked = FALSE
NEXT rexpl
FOR rproj = 1 TO numofprojectiles
Projectile(rproj).Locked = FALSE
NEXT rproj

' Reset the starting values of 
' variables players' ships need to 
' have in the begining of every level.
FOR countplayer = 1 TO numofplayers
MainShip(countplayer).Battery = 0
MainShip(countplayer).Speed = 0
MainShip(countplayer).VortexScale = 1
MainShip(countplayer).Shots = 0
pseconds(countplayer) = 0
MainShip(countplayer).Angle = 0
' Reset that warning message should
' be activated if the player's shield
' power reduces to less than 8%.
procentshield = (100/MainShip(countplayer).MaxShield)*MainShip(countplayer).Shield
IF procentshield>19 THEN warningmsg(countplayer) = TRUE

NEXT countplayer

' Some stupid variable used in ONE
' specific situation with the boss ship.
ExtraExplosion = 0


' Reset the pickups, planets and
' enemy ships.
FOR cplanet = 1 TO 8
Planet(cplanet).Alive = FALSE    
NEXT cplanet
FOR resetship = 1 TO numofships
Ship(resetship).Alive = FALSE
Ship(resetship).Energy = 0
NEXT resetship
FOR cpick = 1 TO 20
Pickup(cpick).Locked = FALSE    
NEXT cpick

' Set the starting positions of players'
' ships.
IF numofplayers = 1 THEN
MainShip(1).RealX = 1200
MainShip(1).RealY = 1200
CamX(1) = MainShip(1).RealX - MainShip(1).X
CamY(1) = MainShip(1).RealY - MainShip(1).Y
END IF
IF numofplayers = 2 THEN
MainShip(1).RealX = 1150
MainShip(1).RealY = 1200
CamX(1) = MainShip(1).RealX - MainShip(1).X
CamY(1) = MainShip(1).RealY - MainShip(1).Y
MainShip(2).RealX = 1250
MainShip(2).RealY = 1200
CamX(2) = MainShip(2).RealX - MainShip(2).X
CamY(2) = MainShip(2).RealY - MainShip(2).Y
END IF

' Randomize a position which will be used
' to spawn a group of enemies on that
' specific location.
repeatrnd1:
centergroupx1 = int(rnd * (MapBorder-200)) + 100
centergroupy1 = int(rnd * (MapBorder-200)) + 100
FOR countplayer = 1 TO numofplayers
IF ABS(centergroupx1-MainShip(countplayer).RealX)<320 AND ABS(centergroupy1-MainShip(countplayer).RealY)<320 THEN GOTO repeatrnd1:
NEXT countplayer

' According to stage set the planets
' and all the enemies.
SELECT CASE Stage
CASE 1
Planet(1).X = 2000
Planet(1).Y = 1800
Planet(1).Typ = 5
Planet(1).Alive = TRUE
Planet(1).TurnLevel = 0.4
Planet(2).X = 700
Planet(2).Y = 500
Planet(2).Typ = 8
Planet(2).Alive = TRUE
Planet(2).TurnLevel = 0.2
Planet(3).X = 1470
Planet(3).Y = 1320
Planet(3).Typ = 2
Planet(3).Alive = TRUE
Planet(3).TurnLevel = 0
FOR initship = 1 TO 8
Ship(initship).Alive = TRUE
Ship(initship).Typ = 1
IF initship>5 THEN Ship(initship).Typ = 2
Ship(initship).Reload = 0
repeatrndc1:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrndc1:
NEXT countplayer
IF initship =1 OR initship = 7 THEN Ship(initship).Energy = 1
IF numofplayers = 2 AND initship = 2 THEN Ship(initship).Energy = 1
NEXT initship
CASE 2
Planet(1).X = 500
Planet(1).Y = 300
Planet(1).Typ = 1
Planet(1).Alive = TRUE
Planet(1).TurnLevel = 0.5
Planet(2).X = 2300
Planet(2).Y = 700
Planet(2).Typ = 6
Planet(2).Alive = TRUE
Planet(2).TurnLevel = 0.4
Planet(3).X = 2100
Planet(3).Y = 2100
Planet(3).Typ = 7
Planet(3).Alive = TRUE
Planet(3).TurnLevel = 0.4
Planet(4).X = 1350
Planet(4).Y = 1360
Planet(4).Typ = 9
Planet(4).Alive = TRUE
Planet(4).TurnLevel = 0
FOR initship = 1 TO 10
Ship(initship).Alive = TRUE
Ship(initship).Typ = 1
IF initship>4 THEN Ship(initship).Typ = 3
IF initship>6 THEN Ship(initship).Typ = 4
IF initship>8 THEN Ship(initship).Typ = 5
Ship(initship).Reload = 0
repeatrndc2:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrndc2:
NEXT countplayer
IF initship=1 OR initship = 7 THEN Ship(initship).Energy = 1
IF numofplayers = 2 AND initship = 2 THEN Ship(initship).Energy = 1
NEXT initship
CASE 3
Planet(1).X = 780
Planet(1).Y = 270
Planet(1).Typ = 3
Planet(1).Alive = TRUE
Planet(1).TurnLevel = 0.1
Planet(2).X = 1600
Planet(2).Y = 2200
Planet(2).Typ = 7
Planet(2).Alive = TRUE
Planet(2).TurnLevel = 0.4
Planet(3).X = 670
Planet(3).Y = 300
Planet(3).Typ = 5
Planet(3).Alive = TRUE
Planet(3).TurnLevel = 0.2
Planet(4).X = 950
Planet(4).Y = 1060
Planet(4).Typ = 9
Planet(4).Alive = TRUE
Planet(4).TurnLevel = 0
FOR initship = 1 TO 14
Ship(initship).Alive = TRUE
Ship(initship).Typ = 2
IF initship = 5 OR initship = 6 or initship = 7 THEN Ship(initship).Typ = 3
IF initship = 8 OR initship = 9 THEN Ship(initship).Typ = 6
IF initship = 10 THEN Ship(initship).Typ = 4
IF initship = 11 THEN Ship(initship).Typ = 4
IF initship = 11 or initship = 12 THEN Ship(initship).Typ = 5
IF initship = 14 THEN Ship(initship).Typ = 7
repeatrndc3:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrndc3:
NEXT countplayer
IF initship<6 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship = 1 OR initship = 14 or initship = 13 THEN Ship(initship).Energy = 1
IF numofplayers = 2 AND initship = 7 THEN Ship(initship).Energy = 1
NEXT initship
CASE 4
Planet(1).X = 580
Planet(1).Y = 470
Planet(1).Typ = 7
Planet(1).Alive = TRUE
Planet(1).TurnLevel = 0.15
Planet(2).X = 1600
Planet(2).Y = 2200
Planet(2).Typ = 8
Planet(2).Alive = TRUE
Planet(2).TurnLevel = 0.4
Planet(3).X = 2000
Planet(3).Y = 1200
Planet(3).Typ = 6
Planet(3).Alive = TRUE
Planet(3).TurnLevel = 0.2
Planet(4).X = 1220
Planet(4).Y = 1100
Planet(4).Typ = 2
Planet(4).Alive = TRUE
Planet(4).TurnLevel = 0
Planet(5).X = 550
Planet(5).Y = 2000
Planet(5).Typ = 4
Planet(5).Alive = TRUE
Planet(5).TurnLevel = 0.1
FOR initship = 1 TO 14
Ship(initship).Alive = TRUE
Ship(initship).Typ = 8
IF initship = 5 OR initship = 6 or initship = 7 THEN Ship(initship).Typ = 5
IF initship = 8 OR initship = 9  or initship = 1 THEN Ship(initship).Typ = 6
IF initship = 10 THEN Ship(initship).Typ = 4
IF initship = 11 THEN Ship(initship).Typ = 7
IF initship = 11 or initship = 12 THEN Ship(initship).Typ = 9
IF initship = 14 THEN Ship(initship).Typ = 10
repeatrndc4:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrndc4:
NEXT countplayer
IF initship<7 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship = 1 OR initship = 14 or initship = 13 THEN Ship(initship).Energy = 1
IF numofplayers = 2 AND initship = 8 THEN Ship(initship).Energy = 1
NEXT initship
CASE 5
Ship(1).Alive = TRUE
Ship(1).Typ = 13
Ship(1).X = 2000
Ship(1).Y = 2000
Ship(2).Alive = TRUE
Ship(2).Typ = 11
Ship(2).X = 1900
Ship(2).Y = 1900
FOR initship = 3 TO 13
Ship(initship).Alive = TRUE
Ship(initship).Typ = 12
Ship(initship).X = int(rnd * 240)+Ship(1).X-120
Ship(initship).Y = int(rnd * 240)+Ship(1).Y-120
NEXT initship
END SELECT

' After all the enemy ships have been set
' init their characteristics according
' to their type.
FOR settype = 1 TO numofships
InitShipCharacteristics settype
NEXT settype

END SUB

SUB PlanetLayer ()

FOR cplanet = 1 TO 8
    
IF Planet(cplanet).Alive = TRUE THEN

IF numofplayers = 2 AND countplayer = 2 THEN GOTO skiptoplanetdraw:

Planet(cplanet).Angle = Planet(cplanet).Angle + Planet(cplanet).TurnLevel
IF Planet(cplanet).Angle>359 THEN Planet(cplanet).Angle = 0
IF Planet(cplanet).Angle<0 THEN Planet(cplanet).Angle = 359

skiptoplanetdraw:

AF2.SprBlit_rotate Planet(cplanet).X-CamX(countplayer),Planet(cplanet).Y-CamY(countplayer), @PlanetSprite.p_data[PlanetSprite.p_dataindex[Planet(cplanet).Typ-1]], Planet(cplanet).Angle
FOR circularmap = 1 TO 8
SELECT CASE circularmap
CASE 1
MapBorder1 = MapBorder
MapBorder2 = 0
CASE 2
MapBorder1 = -MapBorder
MapBorder2 = 0
CASE 3
MapBorder1 = 0
MapBorder2 = MapBorder
CASE 4
MapBorder1 = 0
MapBorder2 = -MapBorder
CASE 5
MapBorder1 = MapBorder
MapBorder2 = MapBorder
CASE 6
MapBorder1 = -MapBorder
MapBorder2 = -MapBorder
CASE 7
MapBorder1 = -MapBorder
MapBorder2 = MapBorder
CASE 8
MapBorder1 = MapBorder
MapBorder2 = -MapBorder
END SELECT
AF2.SprBlit_rotate Planet(cplanet).X-CamX(countplayer)+MapBorder1,Planet(cplanet).Y-CamY(countplayer)+MapBorder2, @PlanetSprite.p_data[PlanetSprite.p_dataindex[Planet(cplanet).Typ-1]], Planet(cplanet).Angle
NEXT circularmap

IF (Planet(cplanet).Typ = 10 AND MainShip(countplayer).Alive = TRUE AND countstageend(countplayer)<131) THEN
IF ABS(Planet(cplanet).X-MainShip(countplayer).RealX-10)<20 AND ABS(Planet(cplanet).Y-MainShip(countplayer).RealY-8)<20 THEN 
countstageend(countplayer) = 131
vorx! = Planet(cplanet).X
vory! = Planet(cplanet).Y
playSample (sample(9))
END IF
END IF

END IF ' End of IF Planet.Alive = TRUE(if a planet is present)

NEXT cplanet

END SUB

SUB InitiatePickup (pix!, piy!, pityp)
    
FOR initpick = 1 TO 20
 
IF Pickup(initpick).Locked = FALSE THEN
Pickup(initpick).X = pix!
Pickup(initpick).Y = piy!
Pickup(initpick).Typ = pityp
Pickup(initpick).Locked = TRUE
EXIT SUB    
END IF
 
NEXT initpick
    
END SUB

SUB PickupLayer ()
    
FOR cpick = 1 TO 20
    
IF Pickup(cpick).Locked = TRUE THEN

addspr = 0
IF Pickup(cpick).Typ > 1 THEN addspr = 6
pickspr = Frame7 + addspr
IF pickspr = 0 THEN pickspr = 1    
AF2.SprBlit Pickup(cpick).X-CamX(countplayer),Pickup(cpick).Y-CamY(countplayer), @PickupSprite.p_data[PickupSprite.p_dataindex[pickspr-1]], GFX_v, GFX_h

FOR circularmap = 1 TO 8
SELECT CASE circularmap
CASE 1
MapBorder1 = MapBorder
MapBorder2 = 0
CASE 2
MapBorder1 = -MapBorder
MapBorder2 = 0
CASE 3
MapBorder1 = 0
MapBorder2 = MapBorder
CASE 4
MapBorder1 = 0
MapBorder2 = -MapBorder
CASE 5
MapBorder1 = MapBorder
MapBorder2 = MapBorder
CASE 6
MapBorder1 = -MapBorder
MapBorder2 = -MapBorder
CASE 7
MapBorder1 = -MapBorder
MapBorder2 = MapBorder
CASE 8
MapBorder1 = MapBorder
MapBorder2 = -MapBorder
END SELECT
AF2.SprBlit Pickup(cpick).X-CamX(countplayer)+MapBorder1,Pickup(cpick).Y-CamY(countplayer)+MapBorder2, @PickupSprite.p_data[PickupSprite.p_dataindex[pickspr-1]], GFX_v, GFX_h
NEXT circularmap

IF MainShip(countplayer).Alive = TRUE AND AF2.SprCollide(Pickup(cpick).X, Pickup(cpick).Y, @PickupSprite.p_data[PickupSprite.p_dataindex[pickspr-1]], MainShip(countplayer).RealX, MainShip(countplayer).RealY, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(countplayer).Sprite-1]]) THEN
Pickup(cpick).Locked = FALSE
playsample (sample(6))
IF GameMode = 1 THEN MainShip(countplayer).Energy = MainShip(countplayer).Energy + 75
IF GameMode = 2 THEN
SELECT CASE Pickup(cpick).Typ
CASE 1
MainShip(countplayer).Shield = MainShip(countplayer).Shield + 3
IF MainShip(countplayer).Shield > MainShip(countplayer).MaxShield THEN MainShip(countplayer).Shield = MainShip(countplayer).MaxShield
CASE 2
IF MainShip(countplayer).WeaponLevel<4 THEN MainShip(countplayer).WeaponLevel = MainShip(countplayer).WeaponLevel + 1
CASE 3
IF MainShip(countplayer).TurnLevel>4 THEN MainShip(countplayer).TurnLevel = MainShip(countplayer).TurnLevel - 2
CASE 4
IF MainShip(countplayer).MaxShield<49 THEN 
MainShip(countplayer).MaxShield = MainShip(countplayer).MaxShield + 7
MainShip(countplayer).Shield = MainShip(countplayer).MaxShield
END IF
CASE 5
IF MainShip(countplayer).Acceleration<0.6 THEN 
MainShip(countplayer).Acceleration = MainShip(countplayer).Acceleration + 0.2
MainShip(countplayer).MaxReverse = MainShip(countplayer).MaxReverse + 0.4
END IF
CASE 6
IF MainShip(countplayer).MaxBattery<20 THEN MainShip(countplayer).MaxBattery = MainShip(countplayer).MaxBattery + 5
END SELECT
END IF
END IF

END IF

NEXT cpick

END SUB

SUB NewPhase ()

' A sub which respawns new enemies in a specific
' stage if one phase has been cleared.

' If you have reached the last phase of the
' current stage another phase mustn't be
' initiated.
IF PhaseNumber = 3 THEN EXIT SUB

' Special situation for stage 5(NO PHASES!).
IF Stage = 5 AND PhaseNumber = 1 THEN EXIT SUB

' Reset all the ships again.
FOR resetship = 1 TO numofships
Ship(resetship).Alive = FALSE
Ship(resetship).Energy = 0
NEXT resetship

' Change phase.
IF PhaseNumber < 3 THEN PhaseNumber = PhaseNumber + 1

' Phase is incomplete again.
PhaseDone = FALSE

' Randomize group points that might be used
' in some phases to spawn groups of enemy ships.
repeatrndp1:
centergroupx1 = int(rnd * (MapBorder-200)) + 100
centergroupy1 = int(rnd * (MapBorder-200)) + 100
FOR countplayer = 1 TO numofplayers
IF ABS(centergroupx1-MainShip(countplayer).RealX)<320 AND ABS(centergroupy1-MainShip(countplayer).RealY)<320 THEN GOTO repeatrndp1:
NEXT countplayer
repeatrndp2:
centergroupx2 = int(rnd * (MapBorder-200)) + 100
centergroupy2 = int(rnd * (MapBorder-200)) + 100
FOR countplayer = 1 TO numofplayers
IF ABS(centergroupx2-MainShip(countplayer).RealX)<320 AND ABS(centergroupy2-MainShip(countplayer).RealY)<320 THEN GOTO repeatrndp2:
NEXT countplayer
repeatrndp3:
centergroupx3 = int(rnd * (MapBorder-200)) + 100
centergroupy3 = int(rnd * (MapBorder-200)) + 100
FOR countplayer = 1 TO numofplayers
IF ABS(centergroupx3-MainShip(countplayer).RealX)<320 AND ABS(centergroupy3-MainShip(countplayer).RealY)<320 THEN GOTO repeatrndp3:
NEXT countplayer

SELECT CASE Stage

' **********************************************
CASE 1 ' Stage 1, Phases 2 and 3 ship initiation
SELECT CASE PhaseNumber
CASE 2
FOR initship = 1 TO 12
Ship(initship).Alive = TRUE
Ship(initship).Typ = 1
IF initship>7 THEN Ship(initship).Typ = 2
IF initship>11 THEN Ship(initship).Typ = 3
Ship(initship).Reload = 0
repeatrnds1c2:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<280 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<280 THEN goto repeatrnds1c2:
NEXT countplayer
IF initship < 5 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship =1 OR initship = 5 OR initship = 10 THEN Ship(initship).Energy = 1
IF numofplayers = 2 AND initship = 7 THEN Ship(initship).Energy = 1
NEXT initship
CASE 3
FOR initship = 1 TO 14
Ship(initship).Alive = TRUE
Ship(initship).Typ = 1
IF initship>4 THEN Ship(initship).Typ = 2
IF initship>11 THEN Ship(initship).Typ = 3
IF initship=14 THEN Ship(initship).Typ = 4
Ship(initship).Reload = 0
repeatrnds1c3:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<280 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<280 THEN goto repeatrnds1c3:
NEXT countplayer
IF initship < 4 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship > 11 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship = 5 OR initship = 10 or initship = 7 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN
IF initship = 3 OR initship = 8 THEN Ship(initship).Energy = 1
END IF
NEXT initship
END SELECT

' **********************************************
CASE 2 ' Stage 2, Phases 2 and 3 ship initiation
SELECT CASE PhaseNumber
CASE 2
FOR initship = 1 TO 16
Ship(initship).Alive = TRUE
Ship(initship).Typ = 1
IF initship<5 THEN Ship(initship).Typ = 2
IF initship=6 THEN Ship(initship).Typ = 5
IF initship=8 THEN Ship(initship).Typ = 5
IF initship=10 OR initship=11 THEN Ship(initship).Typ = 4
IF initship=12 THEN Ship(initship).Typ = 3
IF initship=13 THEN Ship(initship).Typ = 5
IF initship=14 THEN Ship(initship).Typ = 5
IF initship=15 THEN Ship(initship).Typ = 2
IF initship=16 THEN Ship(initship).Typ = 5
Ship(initship).Reload = 0
repeatrnds2c2:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<280 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<280 THEN goto repeatrnds2c2:
NEXT countplayer
IF initship < 6 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship > 13 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship = 1 or initship = 7 or initship = 10 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN 
IF initship = 2 OR initship = 8 THEN Ship(initship).Energy = 1
END IF
NEXT initship
CASE 3
FOR initship = 1 TO 20
Ship(initship).Alive = TRUE
Ship(initship).Typ = 1
IF initship<8 THEN Ship(initship).Typ = 1
IF initship=8 THEN Ship(initship).Typ = 3
IF initship=9 THEN Ship(initship).Typ = 3
IF initship=10 THEN Ship(initship).Typ = 3
IF initship=11 THEN Ship(initship).Typ = 2
IF initship=12 THEN Ship(initship).Typ = 6
IF initship=13 THEN Ship(initship).Typ = 3
IF initship=14 THEN Ship(initship).Typ = 2
IF initship>14 AND initship<19 THEN Ship(initship).Typ = 5
IF initship>18 THEN Ship(initship).Typ = 4
Ship(initship).Reload = 0
repeatrnds2c3:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<280 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<280 THEN goto repeatrnds2c3:
NEXT countplayer
IF initship < 8 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship > 17 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship>12 AND initship<16  THEN
Ship(initship).X = int(rnd * 200)+centergroupx3-100
Ship(initship).Y = int(rnd * 200)+centergroupy3-100
END IF
IF initship = 1 OR initship = 5 OR initship = 15 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN 
IF initship = 2 OR initship = 8 THEN Ship(initship).Energy = 1
END IF
NEXT initship
END SELECT

' **********************************************
CASE 3 ' Stage 3, Phases 2 and 3 ship initiation
SELECT CASE PhaseNumber
CASE 2
FOR initship = 1 TO 16
Ship(initship).Alive = TRUE
Ship(initship).Typ = 8
IF initship = 8 OR initship = 9 THEN Ship(initship).Typ = 6
IF initship > 9 AND initship<12 THEN Ship(initship).Typ = 4
IF initship > 11 THEN Ship(initship).Typ = 5
IF initship > 13 THEN Ship(initship).Typ = 7
IF initship = 16 THEN Ship(initship).Typ = 1
repeatrnds3c2:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrnds3c2:
NEXT countplayer
IF initship < 7 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship > 10 AND initship < 15 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship = 1 OR initship = 14 OR initship = 7 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN 
IF initship = 5 OR initship = 8 THEN Ship(initship).Energy = 1
END IF
NEXT initship
CASE 3
FOR initship = 1 TO 20
Ship(initship).Alive = TRUE
Ship(initship).Typ = 8
IF initship = 2 or initship = 21 or initship = 9 THEN Ship(initship).Typ = 6
IF initship = 10 THEN Ship(initship).Typ = 3
IF initship > 11 AND initship < 14 THEN Ship(initship).Typ = 2
IF initship > 2 AND initship < 7 THEN Ship(initship).Typ = 5
IF initship > 14 AND initship < 17 THEN Ship(initship).Typ = 7
IF initship = 18 OR initship = 19 THEN Ship(initship).Typ = 4
IF initship = 20 THEN Ship(initship).Typ = 9
repeatrnds3c3:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrnds3c3:
NEXT countplayer
IF initship < 7 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship > 10 AND initship < 15 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship > 14 AND initship < 21 THEN
Ship(initship).X = int(rnd * 200)+centergroupx3-100
Ship(initship).Y = int(rnd * 200)+centergroupy3-100
END IF
IF initship = 4 OR initship = 1 OR initship = 14 or initship = 7 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN 
IF initship = 2 OR initship = 8 THEN Ship(initship).Energy = 1
END IF
NEXT initship
END SELECT
' **********************************************
CASE 4 ' Stage 3, Phases 2 and 3 ship initiation
SELECT CASE PhaseNumber
CASE 2
FOR initship = 1 TO 18
Ship(initship).Alive = TRUE
Ship(initship).Typ = 8
IF initship = 6 OR initship = 7 or initship = 8 or initship = 9 THEN Ship(initship).Typ = 5
IF initship = 10 OR initship = 11  or initship = 12 THEN Ship(initship).Typ = 7
IF initship = 18 THEN Ship(initship).Typ = 6
IF initship = 14 THEN Ship(initship).Typ = 6
IF initship = 15 or initship = 16 THEN Ship(initship).Typ = 9
IF initship = 17 THEN Ship(initship).Typ = 10
IF initship = 13 THEN Ship(initship).Typ = 10
repeatrnds4c2:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrnds4c2:
NEXT countplayer
IF initship<8 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship>11 AND initship<16 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship = 1 OR initship = 8 or initship = 14 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN 
IF initship = 10 THEN Ship(initship).Energy = 1
END IF
NEXT initship
CASE 3
FOR initship = 1 TO 22
Ship(initship).Alive = TRUE
Ship(initship).Typ = 8
IF initship = 6 OR initship = 14 or initship = 8 or initship = 21 THEN Ship(initship).Typ = 4
IF initship = 10 OR initship = 11  or initship = 12 or initship = 13 THEN Ship(initship).Typ = 7
IF initship = 18 THEN Ship(initship).Typ = 6
IF initship = 7 THEN Ship(initship).Typ = 6
IF initship = 15 THEN Ship(initship).Typ = 6
IF initship = 16 or initship = 17 or initship = 19 THEN Ship(initship).Typ = 9
IF initship = 20 THEN Ship(initship).Typ = 10
IF initship = 13 THEN Ship(initship).Typ = 10
IF initship = 9 THEN Ship(initship).Typ = 10
IF initship = 22 THEN Ship(initship).Typ = 2
repeatrnds4c3:
Ship(initship).X = int(rnd * (MapBorder-200))+100
Ship(initship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(initship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(initship).Y)<300 THEN goto repeatrnds4c3:
NEXT countplayer
IF initship>2 AND initship<12 THEN
Ship(initship).X = int(rnd * 200)+centergroupx1-100
Ship(initship).Y = int(rnd * 200)+centergroupy1-100
END IF
IF initship>13 AND initship<17 THEN
Ship(initship).X = int(rnd * 200)+centergroupx2-100
Ship(initship).Y = int(rnd * 200)+centergroupy2-100
END IF
IF initship>20 THEN
Ship(initship).X = int(rnd * 200)+centergroupx3-100
Ship(initship).Y = int(rnd * 200)+centergroupy3-100
END IF
IF initship = 3 OR initship = 8 or initship = 14 or initship = 21 THEN Ship(initship).Energy = 1
IF numofplayers = 2 THEN 
IF initship = 2 OR initship = 10 THEN Ship(initship).Energy = 1
END IF
NEXT initship
END SELECT
END SELECT

FOR settype = 1 TO numofships
InitShipCharacteristics settype
NEXT settype
 
END SUB

SUB UpgradeShipScreen

' If you are playing a two player mode and
' second player has been destroyed simply
' change the game mode to one player mode.
' If the first players has been destroyed
' we need to pass all the values from the
' second ship to the first and switch
' to single player mode.
IF numofplayers = 2 THEN
IF MainShip(2).Alive = FALSE THEN numofplayers = 1
IF MainShip(1).Alive = FALSE THEN
numofplayers = 1
' Store the original score of player 1
' (will be needed with top scores
' inputting).
Player1OriginalScore = MainShip(1).Score
' Pass all the values from player 2 to 
' player 1 variables.
MainShip(1).Shield = MainShip(2).Shield
MainShip(1).MaxShield = MainShip(2).MaxShield
MainShip(1).MaxReverse = MainShip(2).MaxReverse
MainShip(1).Acceleration = MainShip(2).Acceleration 
MainShip(1).MaxBattery = MainShip(2).MaxBattery
MainShip(1).WeaponLevel = MainShip(2).WeaponLevel 
MainShip(1).TurnLevel = MainShip(2).TurnLevel 
MainShip(1).StartSprite = MainShip(2).StartSprite
MainShip(1).Sprite = MainShip(2).Sprite
MainShip(1).WeaponPower = MainShip(2).WeaponPower
MainShip(1).Energy = MainShip(2).Energy
MainShip(1).Score = MainShip(2).Score
MainShip(1).Shots = MainShip(2).Shots
MainShip(1).ShipProj = MainShip(2).ShipProj
pseconds(1) = pseconds(2)
MainShip(1).Alive = TRUE
MainShip(2).Alive = FALSE
scoreflag = 1
END IF
END IF

playStreamMusic("Sound/atmosphere.mp3")

ScoreScreen

' A boring code that draws and manages
' the ship upgrade screen. Nothing
' fancy.
FOR countplayer = 1 TO numofplayers 

menupos = 1
KeyFree = FALSE
FOR copt = 1 TO 10
optionfade(copt) = 7
NEXT copt
FOR cupg = 1 TO 20
upgradefade(cupg) = 7
NEXT cupg
upangle = 0
    
DO

screenset workpage, workpage xor 1

upangle! = upangle! + 0.5
IF upangle! > 359 THEN upangle! = 0

AF2.ClearScreen 0

DrawStars 1

FOR copt = 1 TO 10
IF menupos<>copt THEN 
IF optionfade(copt)>10 THEN optionfade(copt) = optionfade(copt) - 5
IF optionfade(copt)<10 THEN optionfade(copt) = 10
END IF
IF menupos=copt THEN
IF optionfade(copt)<42 THEN optionfade(copt) = optionfade(copt) + 5
IF optionfade(copt)>42 THEN optionfade(copt) = 42
END IF
NEXT copt

IF (MULTIKEY(SC_UP) AND KeyFree = TRUE AND countplayer = 1) OR (MULTIKEY(SC_E) AND KeyFree = TRUE AND countplayer = 2) THEN 
menupos = menupos - 1
KeyFree = FALSE
IF menupos < 1 THEN menupos = 1
END IF
IF (MULTIKEY(SC_DOWN) AND KeyFree = TRUE AND countplayer = 1) OR (MULTIKEY(SC_D) AND KeyFree = TRUE AND countplayer = 2) THEN 
menupos = menupos + 1
KeyFree = FALSE
IF menupos > 7 THEN menupos = 7
END IF

spr1 = int(rnd * 2)+ 1
spr2 = 3
sprrnd = int(rnd * 20)+ 1
IF sprrnd > 16 THEN spr2 = 4
rsprnum = 6
IF menupos<7 AND menupos>1 THEN rsprnum=menupos-1

AF2.SprBlit_rotate 66, 54, MiscBuffer1(rsprnum), upangle!
AF2.SprBlit 125, 30, @Sprites3.p_data[Sprites3.p_dataindex[spr1-1]], GFX_v, GFX_h
AF2.SprBlit 125, 60, @Sprites3.p_data[Sprites3.p_dataindex[spr2-1]], GFX_v, GFX_h

IF numofplayers = 2 THEN AF2.PP256fnt_brightness "Player "+STR$(countplayer), 190, 18, 0, 21, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Repair shield", 190, 30, 0, optionfade(1), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Upgrade weapon", 190, 40, 0, optionfade(2), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Upgrade turning", 190, 50, 0, optionfade(3), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Upgrade shield", 190, 60, 0, optionfade(4), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Upgrade engines", 190, 70, 0, optionfade(5), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Upgrade battery", 190, 80, 0, optionfade(6), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Exit", 190, 90, 0, optionfade(7), Font1, GFX_v, GFX_h 

procentshield = (100/MainShip(countplayer).MaxShield)*MainShip(countplayer).Shield

IF (MULTIKEY(SC_ENTER) AND KeyFree = TRUE AND countplayer = 1) OR (MULTIKEY(SC_Q) AND KeyFree = TRUE AND countplayer = 2) THEN
KeyFree = FALSE
SELECT CASE menupos
CASE 1
IF MainShip(countplayer).Energy >= 15 AND MainShip(countplayer).Shield < MainShip(countplayer).MaxShield THEN
MainShip(countplayer).Energy = MainShip(countplayer).Energy - 15
MainShip(countplayer).Shield = MainShip(countplayer).Shield + 1
IF MainShip(countplayer).Shield > MainShip(countplayer).MaxShield THEN MainShip(countplayer).Shield = MainShip(countplayer).MaxShield
playsample (sample(11))
END IF
CASE 2
IF MainShip(countplayer).Energy >= 500 AND MainShip(countplayer).WeaponLevel<4 THEN 
MainShip(countplayer).WeaponLevel = MainShip(countplayer).WeaponLevel + 1
MainShip(countplayer).Energy = MainShip(countplayer).Energy - 500
playsample (sample(12))
END IF
CASE 3
IF MainShip(countplayer).Energy >= 500 AND MainShip(countplayer).TurnLevel>4 THEN 
MainShip(countplayer).TurnLevel = MainShip(countplayer).TurnLevel - 2
MainShip(countplayer).Energy = MainShip(countplayer).Energy - 500
playsample (sample(12))
END IF
CASE 4
IF MainShip(countplayer).Energy >= 450 AND MainShip(countplayer).MaxShield<49 THEN 
MainShip(countplayer).MaxShield = MainShip(countplayer).MaxShield + 7
MainShip(countplayer).Shield = MainShip(countplayer).MaxShield
MainShip(countplayer).Energy = MainShip(countplayer).Energy - 450
playsample (sample(12))
END IF
CASE 5
IF MainShip(countplayer).Energy >= 400 AND MainShip(countplayer).Acceleration<0.6 THEN 
MainShip(countplayer).Acceleration = MainShip(countplayer).Acceleration + 0.2
MainShip(countplayer).MaxReverse = MainShip(countplayer).MaxReverse + 0.4
MainShip(countplayer).Energy = MainShip(countplayer).Energy - 400
playsample (sample(12))
END IF
CASE 6
IF MainShip(countplayer).Energy >= 300 AND MainShip(countplayer).MaxBattery<20 THEN 
MainShip(countplayer).MaxBattery = MainShip(countplayer).MaxBattery + 5
MainShip(countplayer).Energy = MainShip(countplayer).Energy - 300
playsample (sample(12))
END IF
END SELECT
END IF

FOR cupg = 1 TO 20
upgradefade(cupg) = 7
NEXT cupg
IF MainShip(countplayer).WeaponLevel > 0 THEN upgradefade(1) = 0
IF MainShip(countplayer).WeaponLevel = 2 THEN upgradefade(2) = 0
IF MainShip(countplayer).WeaponLevel = 3 THEN upgradefade(3) = 0
IF MainShip(countplayer).WeaponLevel = 4 THEN upgradefade(4) = 0
IF MainShip(countplayer).TurnLevel = 8 THEN upgradefade(5) = 0
IF MainShip(countplayer).TurnLevel = 6 THEN upgradefade(6) = 0
IF MainShip(countplayer).TurnLevel = 4 THEN upgradefade(7) = 0
IF MainShip(countplayer).MaxShield = 35 THEN upgradefade(8) = 0
IF MainShip(countplayer).MaxShield = 42 THEN upgradefade(9) = 0
IF MainShip(countplayer).MaxShield = 49 THEN upgradefade(10) = 0
IF MainShip(countplayer).Acceleration < 0.3 THEN upgradefade(11) = 0
IF MainShip(countplayer).Acceleration >= 0.3 THEN upgradefade(12) = 0
IF MainShip(countplayer).Acceleration >= 0.5 THEN upgradefade(13) = 0
IF MainShip(countplayer).MaxBattery = 10 THEN upgradefade(14) = 0
IF MainShip(countplayer).MaxBattery = 15 THEN upgradefade(15) = 0
IF MainShip(countplayer).MaxBattery = 20 THEN upgradefade(16) = 0

SELECT CASE menupos
CASE 1
req$ = "015"
CASE 2
req$ = "500"    
CASE 3
req$ = "500"
CASE 4
req$ = "450"
CASE 5
req$ = "400"
CASE 6
req$ = "300"
END SELECT

AF2.PP256fntSP_tr.fadecust "Reserve Energy: "+STR$(MainShip(countplayer).Energy)+" Xl", 5, 3, 0, 0, 3, Font1, GFX_v, GFX_h 
IF menupos<7 THEN AF2.PP256fntSP_tr.fadecust "Requires: "+STR$(req$)+" Xl", 190, 3, 0, 0, 3, Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Shield: "+STR$(procentshield)+"%", 5, 100, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Cannons:", 5, 115, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Front", 5+72, 115, 0, 0, upgradefade(1), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Back", 5+72+48, 115, 0, 0, upgradefade(2), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Side", 5+72+48+40, 115, 0, 0, upgradefade(3), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Spread", 5+72+48+40+40, 115, 0, 0, upgradefade(4), Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Turning thrusters:", 5, 130, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Class I", 5+152, 130, 0, 0, upgradefade(5), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Class II", 5+152, 140, 0, 0, upgradefade(6), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Class III", 5+152, 150, 0, 0, upgradefade(7), Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Shield model:", 5, 165, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Aleus I", 5+110, 165, 0, 0, upgradefade(8), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Aleus II", 5+110, 175, 0, 0, upgradefade(9), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Marnacor", 5+110, 185, 0, 0, upgradefade(10), Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Engine model:", 5, 200, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "SW-L1", 5+110, 200, 0, 0, upgradefade(11), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "SW-L2", 5+110+48, 200, 0, 0, upgradefade(12), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "SW-HI", 5+110+48+48, 200, 0, 0, upgradefade(13), Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Battery model:", 5, 215, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Varny-A", 5+120, 215, 0, 0, upgradefade(14), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Varny-B", 5+120+64, 215, 0, 0, upgradefade(15), Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Varny-X", 5+120+64+64, 215, 0, 0, upgradefade(16), Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240

IF (MULTIKEY(SC_ENTER) AND menupos = 7 AND countplayer = 1) OR (MULTIKEY(SC_Q) AND menupos = 7 AND countplayer = 2) THEN GOTO nextship:

JoinScreen

workpage xor = 1 

IF MULTIKEY(SC_F1) THEN
BSAVE "screenshot"+LTRIM$(RTRIM$(STR$(sshot)))+".bmp", 0, 307204
sshot=sshot+1
WHILE MULTIKEY(SC_F1)
WEND
END IF

do 
loop until timer& - st >= (1/65) 
st = timer& 

SLEEP 1

IF MULTIKEY(SC_ENTER) OR MULTIKEY(SC_UP) OR MULTIKEY(SC_DOWN) OR MULTIKEY(SC_E) OR MULTIKEY(SC_D) OR MULTIKEY(SC_Q) THEN GOTO skipkeyrestoreu:
KeyFree = TRUE
skipkeyrestoreu:

LOOP

nextship:

BreakScreen
NEXT countplayer

    
END SUB

SUB ProjectileAI (currentprojectile)
 
' Homing missile "AI". It uses the method
' from the enemy ship's AI. All it does it 
' tells the projectile to follow the player's 
' ship.

' Only projectile typ 9 is homing. 
IF Projectile(currentprojectile).Typ<>9 THEN EXIT SUB

IF numofplayers = 1 THEN
MainShipCheckX = MainShip(1).RealX
MainShipCheckY = MainShip(1).RealY
END IF

IF MainShip(countplayer).RealX > MapBorder - 400 AND Projectile(currentprojectile).X < 400 THEN MainShipCheckX = MainShip(countplayer).RealX - MapBorder
IF MainShip(countplayer).RealX < 400 AND Projectile(currentprojectile).X > MapBorder - 400 THEN MainShipCheckX = MainShip(countplayer).RealX + MapBorder
IF MainShip(countplayer).RealY > MapBorder - 400 AND Projectile(currentprojectile).Y < 400 THEN MainShipCheckY = MainShip(countplayer).RealY - MapBorder
IF MainShip(countplayer).RealY < 400 AND Projectile(currentprojectile).Y > MapBorder - 400 THEN MainShipCheckY = MainShip(countplayer).RealY + MapBorder

IF numofplayers = 2 THEN
MainShipCheckX1 = MainShip(1).RealX
MainShipCheckY1 = MainShip(1).RealY
IF MainShip(1).RealX > MapBorder - 400 AND Projectile(currentprojectile).X < 400 THEN MainShipCheckX1 = MainShip(1).RealX - MapBorder
IF MainShip(1).RealX < 400 AND Projectile(currentprojectile).X > MapBorder - 400 THEN MainShipCheckX1 = MainShip(1).RealX + MapBorder
IF MainShip(1).RealY > MapBorder - 400 AND Projectile(currentprojectile).Y < 400 THEN MainShipCheckY1 = MainShip(1).RealY - MapBorder
IF MainShip(1).RealY < 400 AND Projectile(currentprojectile).Y > MapBorder - 400 THEN MainShipCheckY1 = MainShip(1).RealY + MapBorder

MainShipCheckX2 = MainShip(2).RealX
MainShipCheckY2 = MainShip(2).RealY
IF MainShip(2).RealX > MapBorder - 400 AND Projectile(currentprojectile).X < 400 THEN MainShipCheckX2 = MainShip(2).RealX - MapBorder
IF MainShip(2).RealX < 400 AND Projectile(currentprojectile).X > MapBorder - 400 THEN MainShipCheckX2 = MainShip(2).RealX + MapBorder
IF MainShip(2).RealY > MapBorder - 400 AND Projectile(currentprojectile).Y < 400 THEN MainShipCheckY2 = MainShip(2).RealY - MapBorder
IF MainShip(2).RealY < 400 AND Projectile(currentprojectile).Y > MapBorder - 400 THEN MainShipCheckY2 = MainShip(2).RealY + MapBorder

mship1_to_enemyx = ABS(Projectile(currentprojectile).X-MainShipCheckX1)
mship1_to_enemyy = ABS(Projectile(currentprojectile).Y-MainShipCheckY1)
mship2_to_enemyx = ABS(Projectile(currentprojectile).X-MainShipCheckX2)
mship2_to_enemyy = ABS(Projectile(currentprojectile).Y-MainShipCheckY2)
distance1 = SQR(mship1_to_enemyx^2+mship1_to_enemyy^2)
distance2 = SQR(mship2_to_enemyx^2+mship2_to_enemyy^2)
IF distance1 >= distance2 OR MainShip(1).Alive = FALSE THEN
MainShipCheckX = MainShipCheckX2  ' The current enemy is closer to
MainShipCheckY = MainShipCheckY2  ' closer to the second player.
IF countplayer = 1 THEN EXIT SUB  
END IF
IF distance1 < distance2 OR MainShip(2).Alive = FALSE THEN
MainShipCheckX = MainShipCheckX1
MainShipCheckY = MainShipCheckY1
IF countplayer = 2 THEN EXIT SUB
END IF
END IF

IF MainShipCheckY-Projectile(currentprojectile).Y<>0 THEN shipradangle! = ATN((MainShipCheckX-Projectile(currentprojectile).X)/(MainShipCheckY-Projectile(currentprojectile).Y))

shiptoprojangle! = (shipradangle!* 180)/3.14159

IF MainShipCheckY-Projectile(currentprojectile).Y = 0 THEN
IF MainShipCheckX<Projectile(currentprojectile).X THEN shiptoprojangle! = 270
IF MainShipCheckX>Projectile(currentprojectile).X THEN shiptoprojangle! = 90
END IF

IF MainShipCheckX > Projectile(currentprojectile).X THEN
IF MainShipCheckY < Projectile(currentprojectile).Y THEN shiptoprojangle! = shiptoprojangle!*-1
IF MainShipCheckY > Projectile(currentprojectile).Y THEN shiptoprojangle! = 180-shiptoprojangle!
END IF
IF MainShipCheckX < Projectile(currentprojectile).X THEN 
IF MainShipCheckY < Projectile(currentprojectile).Y THEN shiptoprojangle! = 360 - shiptoprojangle!
IF MainShipCheckY > Projectile(currentprojectile).Y THEN shiptoprojangle! = 180 - shiptoprojangle!
END IF
IF shiptoprojangle! < 0 THEN shiptoprojangle! = 270
IF shiptoprojangle! = 0 AND MainShipCheckY > Projectile(currentprojectile).X THEN shiptoprojangle!=180

IF shiptoprojangle! < 0 THEN shiptoprojangle! = shiptoprojangle! + 360
IF shiptoprojangle! > 359 THEN shiptoprojangle! = shiptoprojangle! - 360

IF shiptoprojangle!>=0 AND shiptoprojangle!<90 THEN quadrant = 1
IF shiptoprojangle!>=90 AND shiptoprojangle!<180 THEN quadrant = 2
IF shiptoprojangle!>=180 AND shiptoprojangle!<270 THEN quadrant = 3
IF shiptoprojangle!>=270 AND shiptoprojangle!<360 THEN quadrant = 4
IF Projectile(currentprojectile).Angle>=0 AND Projectile(currentprojectile).Angle<90 THEN rquadrant = 1
IF Projectile(currentprojectile).Angle>=90 AND Projectile(currentprojectile).Angle<180 THEN rquadrant = 2
IF Projectile(currentprojectile).Angle>=180 AND Projectile(currentprojectile).Angle<270 THEN rquadrant = 3
IF Projectile(currentprojectile).Angle>=270 AND Projectile(currentprojectile).Angle<360 THEN rquadrant = 4

IF rquadrant = 1 THEN
IF quadrant = 2 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel
IF quadrant = 3 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel
IF quadrant = 4 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel
END IF
IF rquadrant = 2 THEN
IF quadrant = 1 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel
IF quadrant = 3 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel
IF quadrant = 4 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel
END IF
IF rquadrant = 3 THEN
IF quadrant = 1 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel
IF quadrant = 2 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel
IF quadrant = 4 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel
END IF
IF rquadrant = 4 THEN
IF quadrant = 1 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel
IF quadrant = 3 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel
IF quadrant = 2 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel
END IF
IF rquadrant = quadrant THEN
IF shiptoprojangle!>Projectile(currentprojectile).Angle then Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle + Projectile(currentprojectile).TurnLevel 
IF shiptoprojangle!<Projectile(currentprojectile).Angle then Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle - Projectile(currentprojectile).TurnLevel 
END IF

IF Projectile(currentprojectile).Angle<0 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle+360
IF Projectile(currentprojectile).Angle>359 THEN Projectile(currentprojectile).Angle = Projectile(currentprojectile).Angle-360
radpangle! = (Projectile(currentprojectile).Angle* 3.14159)/180

Projectile(currentprojectile).X = Projectile(currentprojectile).X + Projectile(currentprojectile).Speed * SIN(radpangle!)
Projectile(currentprojectile).Y = Projectile(currentprojectile).Y - Projectile(currentprojectile).Speed * COS(radpangle!)

FOR plproj=1 TO numofprojectiles
IF Projectile(plproj).Typ < 3 AND Projectile(plproj).Locked = TRUE THEN
IF (plproj<>currentprojectile AND plproj>0 AND currentprojectile>0 AND AF2.SprCollide(Projectile(currentprojectile).X-3, Projectile(currentprojectile).Y-5, @ProjSprite.p_data[ProjSprite.p_dataindex[Projectile(currentprojectile).Sprite-1]], Projectile(plproj).X-3, Projectile(plproj).Y-5, @ProjSprite.p_data[ProjSprite.p_dataindex[Projectile(plproj).Sprite-1]])) THEN 
Projectile(plproj).Locked = FALSE
Projectile(currentprojectile).Locked = FALSE
InitiateExplosion Projectile(currentprojectile).X-5, Projectile(currentprojectile).Y-5, 1, 5
END IF
END IF
NEXT plproj

END SUB

SUB InitShipCharacteristics (inittypeship)
    
SELECT CASE Ship(inittypeship).Typ
CASE 1
Ship(inittypeship).Shield = 1
Ship(inittypeship).TurnLevel = 3
Ship(inittypeship).Speed = 1.5
Ship(inittypeship).AIMode = 1
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 1
Ship(inittypeship).CenterX = 5
Ship(inittypeship).CenterY = 6
Ship(inittypeship).WeaponPower = 1
Ship(inittypeship).Score = 50
CASE 2
Ship(inittypeship).Shield = 1
Ship(inittypeship).TurnLevel = 3
Ship(inittypeship).Speed = 1.8
Ship(inittypeship).AIMode = 1
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 2
Ship(inittypeship).CenterX = 6
Ship(inittypeship).CenterY = 5
Ship(inittypeship).WeaponPower = 1.2
Ship(inittypeship).Score = 60
CASE 3
Ship(inittypeship).Shield = 2
Ship(inittypeship).TurnLevel = 3.5
Ship(inittypeship).Speed = 2
Ship(inittypeship).AIMode = 2
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 3
Ship(inittypeship).CenterX = 13
Ship(inittypeship).CenterY = 7
Ship(inittypeship).WeaponPower = 1.5
Ship(inittypeship).Score = 80
CASE 4
Ship(inittypeship).Shield = 3
Ship(inittypeship).TurnLevel = 1.8
Ship(inittypeship).Speed = 3
Ship(inittypeship).AIMode = 3
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 4
Ship(inittypeship).CenterX = 8
Ship(inittypeship).CenterY = 19
Ship(inittypeship).WeaponPower = 2.7
Ship(inittypeship).Score = 120
CASE 5
Ship(inittypeship).Shield = 3
Ship(inittypeship).TurnLevel = 4
Ship(inittypeship).Speed = 3
Ship(inittypeship).AIMode = 2
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 5
Ship(inittypeship).CenterX = 18
Ship(inittypeship).CenterY = 10
Ship(inittypeship).WeaponPower = 1.6
Ship(inittypeship).Score = 100
CASE 6
Ship(inittypeship).Shield = 4
Ship(inittypeship).TurnLevel = 6
Ship(inittypeship).Speed = 0
Ship(inittypeship).AIMode = 4
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 6
Ship(inittypeship).CenterX = 16
Ship(inittypeship).CenterY = 16
Ship(inittypeship).WeaponPower = 2
Ship(inittypeship).Score = 150
CASE 7
Ship(inittypeship).Shield = 5
Ship(inittypeship).TurnLevel = 2.7
Ship(inittypeship).Speed = 1.2
Ship(inittypeship).AIMode = 5
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 7
Ship(inittypeship).CenterX = 16
Ship(inittypeship).CenterY = 16
Ship(inittypeship).WeaponPower = 3.4
Ship(inittypeship).Score = 200
CASE 8
Ship(inittypeship).Shield = 1
Ship(inittypeship).TurnLevel = 3
Ship(inittypeship).Speed = 3
Ship(inittypeship).AIMode = 6
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 8
Ship(inittypeship).CenterX = 9
Ship(inittypeship).CenterY = 7
Ship(inittypeship).WeaponPower = 1.4
Ship(inittypeship).Score = 80
CASE 9
Ship(inittypeship).Shield = 2
Ship(inittypeship).TurnLevel = 2.7
Ship(inittypeship).Speed = 3.6
Ship(inittypeship).AIMode = 7
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 9
Ship(inittypeship).CenterX = 12
Ship(inittypeship).CenterY = 12
Ship(inittypeship).WeaponPower = 2.1
Ship(inittypeship).Score = 150
CASE 10
Ship(inittypeship).Shield = 6
Ship(inittypeship).TurnLevel = 3.5
Ship(inittypeship).Speed = 3
Ship(inittypeship).AIMode = 8
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 10
Ship(inittypeship).CenterX = 22
Ship(inittypeship).CenterY = 13
Ship(inittypeship).WeaponPower = 2.2 
Ship(inittypeship).Score = 250
CASE 11
Ship(inittypeship).Shield = 40
Ship(inittypeship).TurnLevel = 2.1
Ship(inittypeship).Speed = 1
Ship(inittypeship).AIMode = 9
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 11
Ship(inittypeship).CenterX = 50
Ship(inittypeship).CenterY = 38
Ship(inittypeship).WeaponPower = 3.7  
Ship(inittypeship).WeaponLevel = 4.7 ' Used to count 
                                ' the number of 
                                ' fighters the boss
                                ' ship carries.
Ship(inittypeship).Score = 500
CASE 12
Ship(inittypeship).Shield = 2
Ship(inittypeship).TurnLevel = 3
Ship(inittypeship).Speed = 2.7
Ship(inittypeship).AIMode = 1
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 12
Ship(inittypeship).CenterX = 7
Ship(inittypeship).CenterY = 7
Ship(inittypeship).WeaponPower = 1.4
Ship(inittypeship).Score = 90
CASE 13
Ship(inittypeship).Shield = 15
Ship(inittypeship).TurnLevel = 3
Ship(inittypeship).Speed = 0
Ship(inittypeship).AIMode = 11
Ship(inittypeship).AISubMode = 1
Ship(inittypeship).Sprite = 14
Ship(inittypeship).CenterX = 22
Ship(inittypeship).CenterY = 22
Ship(inittypeship).WeaponPower = 0  
Ship(inittypeship).Score = 500
END SELECT

END SUB

SUB SpawnVortex ()

' Check for the sun in the stage planets(typ
' 2 or 9) and spawn the vortex in upper-left
' corner of it(Planet.Typ = 10).
FOR cplanet = 1 TO 8
IF Planet(cplanet).Typ = 2 OR Planet(cplanet).Typ = 9 THEN
vorx! = Planet(cplanet).X - 80
vory! = Planet(cplanet).Y - 80
END IF
NEXT cplanet
FOR cplanet2 = 1 TO 8
IF Planet(cplanet2).Alive = FALSE THEN
Planet(cplanet2).Alive = TRUE
Planet(cplanet2).X = vorx!
Planet(cplanet2).Y = vory!
Planet(cplanet2).Typ = 10
Planet(cplanet2).TurnLevel = 25
END IF
NEXT cplanet2

END SUB

SUB SpawnShip (shx!, shy!, shtyp, shangle!)

' This sub spawns a set type of a ship on 
' the set location and with the set angle.
' Only used in this game with the boss ship
' to enable the fighters to come out of him.

FOR seekship = 1 TO numofships

IF Ship(seekship).Alive = FALSE THEN
Ship(seekship).Alive = TRUE
Ship(seekship).X = shx!
Ship(seekship).Y = shy!
Ship(seekship).Angle = shangle!
Ship(seekship).Typ = shtyp
InitShipCharacteristics seekship
EXIT SUB
END IF
    
NEXT seekship
    
END SUB

SUB DoBigExplosion ()
    
ExtraExplosion = ExtraExplosion - 1
IF ExtraExplosion = 17 THEN
InitiateExplosion Ship(2).X-10+18*COS(Ship(2).Angle), Ship(2).Y-10+18*SIN(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10-18*COS(Ship(2).Angle), Ship(2).Y-10-18*SIN(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10+18*SIN(Ship(2).Angle), Ship(2).Y-10-18*COS(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10+18*SIN(Ship(2).Angle), Ship(2).Y-10-18*COS(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10+28*COS(Ship(2).Angle), Ship(2).Y-10+28*SIN(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10-28*COS(Ship(2).Angle), Ship(2).Y-10-28*SIN(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10+28*SIN(Ship(2).Angle), Ship(2).Y-10-28*COS(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10-28*SIN(Ship(2).Angle), Ship(2).Y-10+28*COS(Ship(2).Angle), 2, 7
InitiateExplosion Ship(2).X-10, Ship(2).Y-10, 2, 7
END IF
explx1 = INT(RND * 60) - 30
exply1 = INT(RND * 60) - 30
explx2 = INT(RND * 60) - 30
exply2 = INT(RND * 60) - 30
explx3 = INT(RND * 60) - 30
exply3 = INT(RND * 60) - 30
explx4 = INT(RND * 60) - 30
exply4 = INT(RND * 60) - 30
IF ExtraExplosion = 15 THEN
InitiateExplosion Ship(2).X-10+explx1, Ship(2).Y-10+exply1, 2, 7
InitiateExplosion Ship(2).X-10+explx2, Ship(2).Y-10+exply2, 2, 7
InitiateExplosion Ship(2).X-10+explx3, Ship(2).Y-10+exply3, 2, 7
InitiateExplosion Ship(2).X-10+explx4, Ship(2).Y-10+exply4, 2, 7
END IF
IF ExtraExplosion = 13 THEN
InitiateExplosion Ship(2).X-10+explx1, Ship(2).Y-10+exply1, 2, 7
InitiateExplosion Ship(2).X-10+explx2, Ship(2).Y-10+exply2, 2, 7
InitiateExplosion Ship(2).X-10+explx3, Ship(2).Y-10+exply3, 2, 7
InitiateExplosion Ship(2).X-10+explx4, Ship(2).Y-10+exply4, 2, 7
END IF
IF ExtraExplosion = 11 THEN
InitiateExplosion Ship(2).X-10+explx1, Ship(2).Y-10+exply1, 2, 7
InitiateExplosion Ship(2).X-10+explx2, Ship(2).Y-10+exply2, 2, 7
InitiateExplosion Ship(2).X-10+explx3, Ship(2).Y-10+exply3, 2, 7
InitiateExplosion Ship(2).X-10+explx4, Ship(2).Y-10+exply4, 2, 7
END IF
IF ExtraExplosion = 8 THEN
InitiateExplosion Ship(2).X-10+explx1, Ship(2).Y-10+exply1, 2, 7
InitiateExplosion Ship(2).X-10+explx2, Ship(2).Y-10+exply2, 2, 7
InitiateExplosion Ship(2).X-10+explx3, Ship(2).Y-10+exply3, 2, 7
InitiateExplosion Ship(2).X-10+explx4, Ship(2).Y-10+exply4, 2, 7
END IF
IF ExtraExplosion = 5 THEN
InitiateExplosion Ship(2).X-10+explx1, Ship(2).Y-10+exply1, 2, 7
InitiateExplosion Ship(2).X-10+explx2, Ship(2).Y-10+exply2, 2, 7
InitiateExplosion Ship(2).X-10+explx3, Ship(2).Y-10+exply3, 2, 7
InitiateExplosion Ship(2).X-10+explx4, Ship(2).Y-10+exply4, 2, 7
END IF

END SUB

SUB EndGame ()

stopStreamMusic

countendgame = 0

dist1= ABS(MainShip(1).RealX-Ship(1).X)+ABS(MainShip(1).RealY-Ship(1).Y)
dist2= ABS(MainShip(2).RealX-Ship(1).X)+ABS(MainShip(2).RealY-Ship(1).Y)

followplayer = 1
IF dist2<dist1 THEN followplayer = 2
IF dist2>dist1 THEN followplayer = 1
IF MainShip(1).Alive = FALSE THEN followplayer = 2
IF MainShip(2).Alive = FALSE THEN followplayer = 1
IF numofplayers = 1 THEN followplayer = 1

DO
    
IF PlaySound = TRUE THEN FSOUND_Update

screenset workpage, workpage xor 1

AF2.ClearScreen 0 ' Clear the screen.
    
countendgame = countendgame + 2

AF2.Globe Ship(1).X-CamX(followplayer), Ship(1).Y-CamY(followplayer), countendgame * 7, 193, 3, 0.4, 1
GET (100,20)-(639-100,479-20), ScreenBuffer(followplayer)
AF2.SprBlit_rotate.solid 320, 240, FullScreenBuffer(followplayer), MainShip(followplayer).Angle
AF2.SprBlit MainShip(followplayer).X, MainShip(followplayer).Y, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(followplayer).Sprite-1]], GFX_v, GFX_h
AF2.SprBlit_rotate 320, 240, ScreenBuffer(followplayer), MainShip(followplayer).Angle

GET (160,120)-(480,360), ScreenBuffer(1)
PUT (0,0), ScreenBuffer(1), PSET
AF2.Scale2x_320x240

workpage xor = 1

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

LOOP UNTIL countendgame = 50

fadecolor = 31

DO
    
WHILE MULTIKEY(SC_ENTER)
WEND
     
IF PlaySound = TRUE THEN FSOUND_Update

screenset workpage, workpage xor 1

AF2.ClearScreen 0 ' Clear the screen.

LINE (0,0)-(639,479), fadecolor, BF

IF fadecolor > 15 THEN fadecolor = fadecolor - 1

workpage xor = 1

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

IF fadecolor = 20 AND PlayingAgain = FALSE THEN playStreamMusic("Sound/endgame.mp3")

LOOP UNTIL fadecolor < 16

countendgame = 0

IF PlayingAgain = TRUE THEN EXIT SUB

DO
    
Frame2 = (Frame2 MOD 2) + 1    
IF countendgame<1200 AND Frame2 = 2 THEN countendgame = countendgame + 1
    
IF PlaySound = TRUE THEN FSOUND_Update

screenset workpage, workpage xor 1

AF2.ClearScreen 0 ' Clear the screen. 

IF countendgame < 300 THEN 
stextline(1) = "As the white light covered your"
stextline(2) = "ship, you prepared for the worst."
stextline(3) = "But after the wave passed you were"
stextline(4) = "to discover that you ended back in"
stextline(5) = "the Taala Region, just few sectors"
stextline(6) = "away from the Black Passage."
END IF
IF countendgame > 299 AND countendgame < 600 THEN 
stextline(1) = "You will need several Republic"
stextline(2) = "rotations to get back on the path"
stextline(3) = "to home but you were happy to"
stextline(4) = "escape alive from this mysterious"
stextline(5) = "imprisonment."
stextline(6) = ""
END IF
IF countendgame > 599 AND countendgame < 900 THEN 
stextline(1) = "The Republic Guard will be most"
stextline(2) = "interested in your report. Before"
stextline(3) = "the explosion you were able to"
stextline(4) = "detect a distress signal coming"
stextline(5) = "from the module and the location"
stextline(6) = "where it was sent."
END IF
IF countendgame > 899 AND countendgame < 1200 THEN 
stextline(1) = "You also managed to pickup a word,"
stextline(2) = "unknown to you, repeating in the"
stextline(3) = "distress signal - 'ARES'"
stextline(4) = "You have a strange feeling that"
stextline(5) = "this story is far from over."
stextline(6) = ""
END IF
IF countendgame > 1199 THEN 
stextline(1) = ""
stextline(2) = ""
stextline(3) = "T H E  E N D"
stextline(4) = ""
stextline(5) = ""
stextline(6) = ""
END IF

FOR csline = 1 TO 6
AF2.PP256fntSP_tr.fadecust stextline(csline), 0, 20+csline*10, 0, 1, 0, Font1, GFX_v, GFX_h 
NEXT csline
PUT (226,135), MiscBuffer2(8), TRANS
GET (160,0)-(480,240), ScreenBuffer(1)

AF2.ClearScreen 0
DrawStars 2
PUT (0,0), ScreenBuffer(1), TRANS
AF2.Scale2x_320x240

workpage xor = 1

do 
loop until timer& - st >= (1/50) 
st = timer& 

SLEEP 1
    
LOOP UNTIL MULTIKEY(SC_ESCAPE)

END SUB

SUB PrintShipStatus (setfade)
 
' This sub is used to display the status of
' players' ships only in two players mode
' and after the Scale2X or the double stretch
' calls(in real 640*480 resolution). Since I
' had to double this code and it's rather
' bulky I've put it in a separate sub. This
' part of code for one player mode is inside
' the main loop. I decided to paste the 
' status text in real size in two players mode
' to conserve visible space.
procentshield = (100/MainShip(2).MaxShield)*MainShip(2).Shield
procentbattery = 100-(100/MainShip(2).MaxBattery)*MainShip(2).Battery
AF2.PP256fntSP_tr.fadecust "Shield: "+STR$(procentshield)+"%", 5, 445, 0, 0, setfade, Font1, GFX_v, GFX_h 
IF procentshield<20 AND Frame3 < 5 THEN AF2.PP256fntSP_tr.fadecust "        "+STR$(procentshield)+"%", 5, 445, 0, 0, 5, Font1, GFX_v, GFX_h 
IF MainShip(2).Shield = 0 THEN AF2.PP256fntSP_tr.fadecust "        "+STR$(procentshield)+"%", 5, 445, 0, 0, 5, Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Battery: "+STR$(procentbattery)+"%", 5, 455, 0, 0, setfade, Font1, GFX_v, GFX_h 
IF GameMode = 1 THEN AF2.PP256fntSP_tr.fadecust "Reserve energy: "+STR$(MainShip(2).Energy)+" Xl", 5, 465, 0, 0, setfade, Font1, GFX_v, GFX_h 
sxpos% = MapBorder/2 - MainShip(2).RealX
sypos% = MapBorder/2 - MainShip(2).RealY
plusx$ = "-"
plusy$ = "-"
zerosx$ = ""
zerosy$ = ""
IF sxpos%>=0 THEN plusx$ = "+"
IF sypos%>=0 THEN plusy$ = "+"
IF ABS(sxpos%)<1000 THEN zerosx$ = "0"
IF ABS(sxpos%)<100 THEN zerosx$ = "00"
IF ABS(sxpos%)<10 THEN zerosx$ = "000"
IF ABS(sypos%)<1000 THEN zerosy$ = "0"
IF ABS(sypos%)<100 THEN zerosy$ = "00"
IF ABS(sypos%)<10 THEN zerosy$ = "000"
AF2.PP256fntSP_tr.fadecust "X: "+plusx$+zerosx$+STR$(ABS(sxpos%)), 5, 3, 0, 0, setfade, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Y: "+plusy$+zerosy$+STR$(ABS(sypos%)), 5, 13, 0, 0, setfade, Font1, GFX_v, GFX_h 
zeross$ = ""
IF ABS(MainShip(2).Score)<10000 THEN zeross$ = "0"
IF ABS(MainShip(2).Score)<1000 THEN zeross$ = "00"
IF ABS(MainShip(2).Score)<100 THEN zeross$ = "000"
IF ABS(MainShip(2).Score)<10 THEN zeross$ = "0000"
IF GameMode = 1 THEN AF2.PP256fntSP_tr.fadecust "Score: "+zeross$+STR$(MainShip(2).Score), 210, 3, 0, 0, setfade, Font1, GFX_v, GFX_h 

procentshield = (100/MainShip(1).MaxShield)*MainShip(1).Shield
procentbattery = 100-(100/MainShip(1).MaxBattery)*MainShip(1).Battery
AF2.PP256fntSP_tr.fadecust "Shield: "+STR$(procentshield)+"%", 334, 445, 0, 0, setfade, Font1, GFX_v, GFX_h 

IF procentshield<20 AND Frame3 < 5 THEN AF2.PP256fntSP_tr.fadecust "        "+STR$(procentshield)+"%", 334, 445, 0, 0, 5, Font1, GFX_v, GFX_h 
IF MainShip(1).Shield = 0 THEN AF2.PP256fntSP_tr.fadecust "        "+STR$(procentshield)+"%", 334, 445, 0, 0, 5, Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Battery: "+STR$(procentbattery)+"%", 334, 455, 0, 0, setfade, Font1, GFX_v, GFX_h 
IF GameMode = 1 THEN AF2.PP256fntSP_tr.fadecust "Reserve energy: "+STR$(MainShip(1).Energy)+" Xl", 334, 465, 0, 0, setfade, Font1, GFX_v, GFX_h 
sxpos% = MapBorder/2 - MainShip(1).RealX
sypos% = MapBorder/2 - MainShip(1).RealY
plusx$ = "-"
plusy$ = "-"
zerosx$ = ""
zerosy$ = ""
IF sxpos%>=0 THEN plusx$ = "+"
IF sypos%>=0 THEN plusy$ = "+"
IF ABS(sxpos%)<1000 THEN zerosx$ = "0"
IF ABS(sxpos%)<100 THEN zerosx$ = "00"
IF ABS(sxpos%)<10 THEN zerosx$ = "000"
IF ABS(sypos%)<1000 THEN zerosy$ = "0"
IF ABS(sypos%)<100 THEN zerosy$ = "00"
IF ABS(sypos%)<10 THEN zerosy$ = "000"
AF2.PP256fntSP_tr.fadecust "X: "+plusx$+zerosx$+STR$(ABS(sxpos%)), 334, 3, 0, 0, setfade, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Y: "+plusy$+zerosy$+STR$(ABS(sypos%)), 334, 13, 0, 0, setfade, Font1, GFX_v, GFX_h 
zeross$ = ""
IF ABS(MainShip(1).Score)<10000 THEN zeross$ = "0"
IF ABS(MainShip(1).Score)<1000 THEN zeross$ = "00"
IF ABS(MainShip(1).Score)<100 THEN zeross$ = "000"
IF ABS(MainShip(1).Score)<10 THEN zeross$ = "0000"
IF GameMode = 1 THEN AF2.PP256fntSP_tr.fadecust "Score: "+zeross$+STR$(MainShip(1).Score), 540, 3, 0, 0, setfade, Font1, GFX_v, GFX_h 

END SUB

SUB ScoreScreen ()
    
FOR countplayer = 1 TO numofplayers 

countloop = 0

DO

screenset workpage, workpage xor 1

countloop = countloop + 1
IF countloop>152 THEN countloop = 152

AF2.ClearScreen 0

DrawStars 1
        
IF numofplayers = 2 THEN AF2.PP256fntSP_tr.fadecust "Player "+STR$(countplayer), 20, 20, 0, 0, 2, Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Current score:", 20, 40, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Stage time:", 20, 60, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Number of shots:", 20, 80, 0, 0, 0, Font1, GFX_v, GFX_h 
AF2.PP256fntSP_tr.fadecust "Shield power:", 20, 100, 0, 0, 0, Font1, GFX_v, GFX_h 

AF2.PP256fntSP_tr.fadecust "Total score:", 20, 130, 0, 0, 0, Font1, GFX_v, GFX_h 

LINE (148,113)-(288,113), 15
IF countloop  = 31 OR countloop = 61 OR countloop = 91 OR countloop = 121 OR countloop = 151 THEN playsample (sample(13))
IF countloop>30 THEN AF2.PP256fntSP_tr.fadecust "+ "+STR$(MainShip(countplayer).Score), 150, 40, 0, 0, 0, Font1, GFX_v, GFX_h 
IF countloop>60 THEN AF2.PP256fntSP_tr.fadecust "- "+STR$(pseconds(countplayer))+"/2 = - "+STR$(pseconds(countplayer)/2), 150, 60, 0, 0, 0, Font1, GFX_v, GFX_h 
IF countloop>90 THEN AF2.PP256fntSP_tr.fadecust "- "+STR$(MainShip(countplayer).Shots)+"/4 = - "+STR$(MainShip(countplayer).Shots/4), 150, 80, 0, 0, 0, Font1, GFX_v, GFX_h 
procentshield = (100/MainShip(countplayer).MaxShield)*MainShip(countplayer).Shield
IF countloop>120 THEN AF2.PP256fntSP_tr.fadecust "+ "+STR$(procentshield)+"*4 = + "+STR$(procentshield*4), 150, 100, 0, 0, 0, Font1, GFX_v, GFX_h 

totalscore = MainShip(countplayer).Score - (pseconds(countplayer)/2) - (MainShip(countplayer).Shots/4)+(procentshield*4)
IF totalscore < 0 THEN totalscore = 0

IF countloop>150 THEN AF2.PP256fntSP_tr.fadecust "  "+STR$(totalscore), 150, 130, 0, 0, 0, Font1, GFX_v, GFX_h 
IF countloop=152 THEN AF2.PP256fntSP_tr.fadecust "Press Fire", 20, 180, 0, 0, 0, Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240
    
JoinScreen

workpage xor = 1 

IF MULTIKEY(SC_F1) THEN
BSAVE "screenshot"+LTRIM$(RTRIM$(STR$(sshot)))+".bmp", 0, 307204
sshot=sshot+1
WHILE MULTIKEY(SC_F1)
WEND
END IF

do 
loop until timer& - st >= (1/65) 
st = timer& 

SLEEP 1

LOOP UNTIL (countplayer = 1 AND MULTIKEY(SC_ENTER) AND countloop = 152) OR (countplayer = 2 AND MULTIKEY(SC_Q) AND countloop = 152)

MainShip(countplayer).Score = totalscore

BreakScreen

WHILE MULTIKEY(SC_ENTER)
WEND

NEXT countplayer

END SUB

SUB ChoosePlayers ()
    
menupos = 1
FOR copt = 1 TO 5
optionfade(copt) = 7
NEXT copt

DO

Frame2 = (Frame2 MOD 2) + 1

IF PlaySound = TRUE THEN FSOUND_Update

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

        FOR i = 0 TO UBOUND(Stars)
            Stars(i).z = Stars(i).z + Stars(i).zvel     'move it
            IF Stars(i).z > 255 THEN                'check for camera LENS
                Stars(i).z = 0                      'ReInit Z value
            END IF

            sx! = Stars(i).x                        'StarX
            sy! = Stars(i).y                        'cleans the projectioon
            sz! = Stars(i).z                        'algo. ;*)
            Distance% = (LENS - sz!)                'get Distance
            IF Distance% THEN                       'if dist>0 then
                'Projection formula
                x% = XCENTER + (LENS * sx! / Distance%)
                y% = YCENTER - (LENS * sy! / Distance%)

            ELSE
                                        'do nothing
                                        'you wouldn't wan't to
                                        'divide by 0 would ya? :*)
            END IF
            clr% = sz!/24+164            'z shading
                                        'z=0 is the farthest
                                        'z=255 is the nearest
            PSET (x%, y%), clr%         'Draw each star

        NEXT i
        
FOR copt = 1 TO 5
IF menupos<>copt THEN 
IF optionfade(copt)>10 THEN optionfade(copt) = optionfade(copt) - 5
IF optionfade(copt)<10 THEN optionfade(copt) = 10
END IF
IF menupos=copt THEN
IF optionfade(copt)<42 THEN optionfade(copt) = optionfade(copt) + 5
IF optionfade(copt)>42 THEN optionfade(copt) = 42
END IF
NEXT copt

IF MULTIKEY(SC_UP) AND KeyFree = TRUE THEN 
menupos = menupos - 1
KeyFree = FALSE
IF menupos < 1 THEN menupos = 1
END IF
IF MULTIKEY(SC_DOWN) AND KeyFree = TRUE THEN 
menupos = menupos + 1
KeyFree = FALSE
IF menupos > 2 THEN menupos = 2
END IF

IF MULTIKEY(SC_ENTER) AND KeyFree = TRUE THEN
SELECT CASE menupos
CASE 1
numofplayers = 1
AF2.PP256fnt_brightness "SINGLE PLAYER", 112, 110, 0, optionfade(1), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "TWO PLAYERS COOPERATIVE", 76, 120, 0, optionfade(2), Font1, GFX_v, GFX_h 
AF2.Scale2x_320x240
EXIT SUB
CASE 2
numofplayers = 2
AF2.PP256fnt_brightness "SINGLE PLAYER", 112, 110, 0, optionfade(1), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "TWO PLAYERS COOPERATIVE", 76, 120, 0, optionfade(2), Font1, GFX_v, GFX_h 
AF2.Scale2x_320x240
EXIT SUB
END SELECT
END IF

AF2.PP256fnt_brightness "SINGLE PLAYER", 112, 110, 0, optionfade(1), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "TWO PLAYERS COOPERATIVE", 76, 120, 0, optionfade(2), Font1, GFX_v, GFX_h
AF2.Scale2x_320x240

JoinScreen

workpage xor = 1

do 
loop until timer& - st >= (1/65) 
st = timer& 

SLEEP 1 

IF MULTIKEY(SC_ENTER) OR MULTIKEY(SC_UP) OR MULTIKEY(SC_DOWN) THEN GOTO skipkeyrestore2:
KeyFree = TRUE
skipkeyrestore2:

LOOP 

END SUB

SUB AddShips ()

' A sub that adds ships in game mode 2(head on
' on head) when there is less than 4 of them
' in the play field.

sumships = 0

FOR checkship = 1 TO numofships
IF Ship(checkship).Alive = TRUE THEN sumships = sumships + 1   
NEXT checkship

' If there is less than 4 ships in the play field
' spawn 1 or 2 new ones.
IF sumships < 4 THEN

' Randomize the number of new ships(1 or 2).
numofnewships = INT(RND * 2) + 1  

added_ships = 0
' Loop through the new ships(1 or 2).
FOR newship = 1 TO numofships

IF Ship(newship).Alive = FALSE THEN
    
added_ships = added_ships + 1

' Randomize ship's type(it can be 1, 2 or 3)
rndtyp = INT(RND * 5) + 1
IF rndtyp < 3 THEN styp = 1
IF rndtyp > 2 AND rndtyp < 5 THEN styp = 2
IF rndtyp = 5 THEN styp = 3
' Randomize if the ship carries a pickup and 
' its type(what upgrade the spawn pickup gives).
rndpickup = INT(RND * 110) + 1
picktyp = 0
IF rndpickup > 10 AND rndpickup < 20 THEN picktyp = 1
IF rndpickup > 50 AND rndpickup < 62 THEN picktyp = 1
IF rndpickup > 19 AND rndpickup < 24 THEN picktyp = 2
IF rndpickup > 23 AND rndpickup < 29 THEN picktyp = 3
IF rndpickup > 28 AND rndpickup < 36 THEN picktyp = 5
IF rndpickup > 35 AND rndpickup < 42 THEN picktyp = 6

' If the program has set the required number
' of new ships exit sub.
IF added_ships > numofnewships THEN EXIT SUB

' Set ships type and the pickup it carries.
Ship(newship).Energy = picktyp
Ship(newship).Reload = 0
Ship(newship).Alive = TRUE
Ship(newship).Typ = styp

' Randomize the new ship's position
repeatrndads:
Ship(newship).X = int(rnd * (MapBorder-200))+100
Ship(newship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF ABS(MainShip(countplayer).RealX-Ship(newship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(newship).Y)<300 THEN GOTO repeatrndads:
NEXT countplayer

InitShipCharacteristics newship

END IF

NEXT newship
    
END IF
    
END SUB

SUB InitHeadOnHead ()

PhaseNumber = 1
countplayerdeath(1) = 0
countplayerdeath(2) = 0
countstageend(1) = 0
countstageend(2) = 0
CountStartStage = 60
PhaseDone = FALSE

numofplayers = 2
GameMode = 2

warningmsg(1) = TRUE
warningmsg(2) = TRUE

FOR rexpl = 1 TO numofexplosions
Explosion(rexpl).Locked = FALSE
NEXT rexpl
FOR rproj = 1 TO numofprojectiles
Projectile(rproj).Locked = FALSE
NEXT rproj

FOR cplanet = 1 TO 8
Planet(cplanet).Alive = FALSE    
NEXT cplanet

FOR resetship = 1 TO numofships
Ship(resetship).Alive = FALSE
Ship(resetship).Energy = 0
NEXT resetship

FOR cpick = 1 TO 20
Pickup(cpick).Locked = FALSE    
NEXT cpick  

MainShip(1).RealX = 600
MainShip(1).RealY = MapBorder/2
CamX(1) = MainShip(1).RealX - MainShip(1).X
CamY(1) = MainShip(1).RealY - MainShip(1).Y
MainShip(2).RealX = MapBorder - 600
MainShip(2).RealY = MapBorder/2
CamX(2) = MainShip(2).RealX - MainShip(2).X
CamY(2) = MainShip(2).RealY - MainShip(2).Y  

MainShip(1).StartSprite = 2
MainShip(2).StartSprite = 6

FOR countplayer = 1 TO numofplayers
MainShip(countplayer).Alive = TRUE
MainShip(countplayer).Shield = 35
MainShip(countplayer).Score = 0
MainShip(countplayer).Shots = 0
MainShip(countplayer).ShipProj = countplayer

MainShip(countplayer).MaxShield = 35 'higher better(2 more levels)
MainShip(countplayer).MaxReverse = 1.4   ' higher better(connected with acceleration)
MainShip(countplayer).Acceleration = 0.2 ' higher better(2 more levels)
MainShip(countplayer).MaxBattery = 10 ' higher better(balance)
MainShip(countplayer).WeaponLevel = 1 ' highest(the best) is 4
MainShip(countplayer).TurnLevel = 8 'lowest(the best) possible is 4

MainShip(countplayer).Battery = 0
MainShip(countplayer).Speed = 0
MainShip(countplayer).Sprite = MainShip(countplayer).StartSprite
MainShip(countplayer).WeaponPower = 1.3
MainShip(countplayer).Energy = 0

MainShip(countplayer).X = 310
MainShip(countplayer).Y = 232

MainShip(countplayer).Angle = 0

NEXT countplayer

' Randomize enemy ships' types(it can be
' 1, 2 or 3)
rndtyp = INT(RND * 5) + 1
IF rndtyp < 3 THEN styp = 1
IF rndtyp > 2 AND rndtyp < 5 THEN styp = 2
IF rndtyp = 5 THEN styp = 3
' Randomize if they carry a pickup and their
' typ(what upgrade the spawn pickup gives).
rndpickup = INT(RND * 110) + 1
picktyp = 0
IF rndpickup > 10 AND rndpickup < 20 THEN picktyp = 1
IF rndpickup > 50 AND rndpickup < 62 THEN picktyp = 1
IF rndpickup > 19 AND rndpickup < 24 THEN picktyp = 2
IF rndpickup > 23 AND rndpickup < 29 THEN picktyp = 3
IF rndpickup > 28 AND rndpickup < 36 THEN picktyp = 5
IF rndpickup > 35 AND rndpickup < 42 THEN picktyp = 6

' Loop through 6 ships to spawn.
FOR newship = 1 TO 6

' Set their typ and the pickup they carry.
Ship(newship).Energy = picktyp
Ship(newship).Reload = 0
Ship(newship).Alive = TRUE
Ship(newship).Typ = styp

' Randomize the new ship's position
repeatrndinithh:
Ship(newship).X = int(rnd * (MapBorder-200))+100
Ship(newship).Y = int(rnd * (MapBorder-200))+100
FOR countplayer = 1 TO numofplayers
IF (ABS(MainShip(countplayer).RealX-Ship(newship).X)<300 AND ABS(MainShip(countplayer).RealY-Ship(newship).Y)<300) THEN GOTO repeatrndinithh:
NEXT countplayer

InitShipCharacteristics newship

NEXT newship

Planet(5).X = MapBorder/2 - 5
Planet(5).Y = MapBorder/2 - 5
Planet(5).Alive = TRUE
Planet(5).Typ = 2

' Randomize number of planets(2 or 3).
numofplanets = INT(RND * 2) + 2  

' Loop through the planets.
FOR cplanet = 1 TO numofplanets

' Randomize their type.
rndtyp = INT(RND * 5) + 1
IF rndtyp = 1 THEN pltyp = 5
IF rndtyp = 2 THEN pltyp = 1
IF rndtyp = 3 THEN pltyp = 7
IF rndtyp = 4 THEN pltyp = 8
IF rndtyp = 5 THEN pltyp = 6

Planet(cplanet).Alive = TRUE
Planet(cplanet).TurnLevel = 0.1
Planet(cplanet).Typ = pltyp
repeatplanetrnd:
Planet(cplanet).X = int(rnd * (MapBorder-200))+100
Planet(cplanet).Y = int(rnd * (MapBorder-200))+100
IF ABS(Planet(cplanet).X-Planet(5).X)<100 AND ABS(Planet(cplanet).Y-Planet(5).Y)<100 THEN GOTO repeatplanetrnd:

NEXT cplanet

END SUB

SUB OtherShipLayer ()
    
' Draw the other player's ship if the game
' is played in two player's mode.
IF countplayer = 2 THEN ' If we are managing player 2(countplayer = 2)
                        ' draw the player one ship on appropriate
                        ' positon(use CamX(2) and CamY(2)!) and draw
                        ' the extra "burner" sprite if the first
                        ' player is pushing the up key.
IF MULTIKEY(SC_UP) AND countstageend(1)<131 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+10, MainShip(1).RealY-CamY(2)+8, @Sprites1.p_data[Sprites1.p_dataindex[4-1]], -MainShip(1).Angle
IF countstageend(1)<131 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+10, MainShip(1).RealY-CamY(2)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF countstageend(1)>130 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_scale.rotate MainShip(1).RealX-CamX(2)+10, MainShip(1).RealY-CamY(2)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], MainShip(1).VortexScale, MainShip(1).VortexScale, -MainShip(1).Angle 
IF MainShip(2).RealX > MapBorder - 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+MapBorder+10,MainShip(1).RealY-CamY(2)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealX < 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)-MapBorder+10,MainShip(1).RealY-CamY(2)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealY > MapBorder - 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+10,MainShip(1).RealY-CamY(2)+MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealY < 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+10,MainShip(1).RealY-CamY(2)-MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealX > MapBorder - 300 AND MainShip(2).RealY > MapBorder - 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+MapBorder+10,MainShip(1).RealY-CamY(2)+MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealX < 300 AND MainShip(2).RealY < 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)-MapBorder+10,MainShip(1).RealY-CamY(2)-MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealX > MapBorder - 300 AND MainShip(2).RealY < 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)+MapBorder+10,MainShip(1).RealY-CamY(2)-MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
IF MainShip(2).RealY > MapBorder - 300 AND MainShip(2).RealX < 300 AND MainShip(1).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(1).RealX-CamX(2)-MapBorder+10,MainShip(1).RealY-CamY(2)+MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(1).Sprite-1]], -MainShip(1).Angle
END IF
IF numofplayers = 2 AND countplayer = 1 THEN ' Same thing for the
                                             ' first player. Here we
                                             ' need to specify that
                                             ' this code should only
                                             ' be executed if the
                                             ' game is played in
                                             ' two players mode since
                                             ' countplayer equals 1 in
                                             ' one player mode too.
                                             ' In one player mode
                                             ' countplayer is never 2
                                             ' so we do not need that
                                             ' condition with the first
                                             ' IF clause.
IF MULTIKEY(SC_E) AND countstageend(2)<131 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+10, MainShip(2).RealY-CamY(1)+8, @Sprites1.p_data[Sprites1.p_dataindex[4-1]], -MainShip(2).Angle
IF countstageend(2)<131 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+10, MainShip(2).RealY-CamY(1)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF countstageend(2)>130 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_scale.rotate MainShip(2).RealX-CamX(1)+10, MainShip(2).RealY-CamY(1)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], MainShip(2).VortexScale, MainShip(2).VortexScale, -MainShip(2).Angle 
IF MainShip(1).RealX > MapBorder - 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+MapBorder+10,MainShip(2).RealY-CamY(1)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealX < 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)-MapBorder+10,MainShip(2).RealY-CamY(1)+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealY > MapBorder - 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+10,MainShip(2).RealY-CamY(1)+MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealY < 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+10,MainShip(2).RealY-CamY(1)-MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealX > MapBorder - 300 AND MainShip(1).RealY > MapBorder - 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+MapBorder+10,MainShip(2).RealY-CamY(1)+MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealX < 300 AND MainShip(1).RealY < 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)-MapBorder+10,MainShip(2).RealY-CamY(1)-MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealX > MapBorder - 300 AND MainShip(1).RealY < 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)+MapBorder+10,MainShip(2).RealY-CamY(1)-MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
IF MainShip(1).RealY > MapBorder - 300 AND MainShip(1).RealX < 300 AND MainShip(2).Alive = TRUE THEN AF2.SprBlit_rotate MainShip(2).RealX-CamX(1)-MapBorder+10,MainShip(2).RealY-CamY(1)+MapBorder+8, @Sprites1.p_data[Sprites1.p_dataindex[MainShip(2).Sprite-1]], -MainShip(2).Angle
END IF    
    
END SUB

SUB Options ()
    
FOR copt = 1 TO 6
optionfade(copt) = 10
NEXT copt
menupos = 1

DO

FPS = FPS + 1                     ' Used to count FPS.
if StartTime& + 1 < timer then
 FPS2 = FPS
 FPS = 0
 seconds = seconds + 1
 StartTime& = timer
end if

Frame2 = (Frame2 MOD 2) + 1

IF PlaySound = TRUE THEN FSOUND_Update

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

DrawStars 1
        
FOR copt = 1 TO 6
IF menupos<>copt THEN 
IF optionfade(copt)>10 THEN optionfade(copt) = optionfade(copt) - 5
IF optionfade(copt)<10 THEN optionfade(copt) = 10
END IF
IF menupos=copt THEN
IF optionfade(copt)<42 THEN optionfade(copt) = optionfade(copt) + 5
IF optionfade(copt)>42 THEN optionfade(copt) = 42
END IF
NEXT copt

sfxv$ = "0 %"
IF SFXVolume = 1 THEN sfxv$ = "25 %"
IF SFXVolume = 2 THEN sfxv$ = "50 %"
IF SFXVolume = 3 THEN sfxv$ = "75 %"
IF SFXVolume = 4 THEN sfxv$ = "100 %"
musicv$ = "0 %"
IF MusicVolume = 1 THEN musicv$ = "25 %"
IF MusicVolume = 2 THEN musicv$ = "50 %"
IF MusicVolume = 3 THEN musicv$ = "75 %"
IF MusicVolume = 4 THEN musicv$ = "100 %"
grmode$ = "SCALE2X"
IF GraphicMode = 2 THEN grmode$ = "STRETCH"
gspeed$ = "SLOW"
IF fpslimit = 33 THEN gspeed$ = "NORMAL"

AF2.PP256fnt_brightness "SFX VOLUME: " + sfxv$, 93, 85, 0, optionfade(1), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "MUSIC VOLUME: " + musicv$, 93, 95, 0, optionfade(2), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "PALETTE: " + pal$, 93, 105, 0, optionfade(3), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "GRAPHIC MODE: "+grmode$, 93, 115, 0, optionfade(4), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "GAME SPEED: "+gspeed$, 93, 125, 0, optionfade(5), Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "BACK TO MAIN MENU", 93, 135, 0, optionfade(6), Font1, GFX_v, GFX_h 
AF2.Scale2x_320x240

IF MULTIKEY(SC_UP) AND KeyFree = TRUE THEN 
menupos = menupos - 1
KeyFree = FALSE
IF menupos < 1 THEN menupos = 1
END IF
IF MULTIKEY(SC_DOWN) AND KeyFree = TRUE THEN 
menupos = menupos + 1
KeyFree = FALSE
IF menupos > 6 THEN menupos = 6
END IF

IF MULTIKEY(SC_ENTER) AND KeyFree = TRUE THEN
KeyFree = FALSE
SELECT CASE menupos
CASE 1
SFXVolume = SFXVolume + 1
IF SFXVolume > 4 THEN SFXVolume = 0
IF SFXVolume = 0 THEN SetVol% = 0
IF SFXVolume = 1 THEN SetVol% = 63
IF SFXVolume = 2 THEN SetVol% = 126
IF SFXVolume = 3 THEN SetVol% = 190
IF SFXVolume = 4 THEN SetVol% = 255
IF PlaySound = TRUE THEN setSoundVolume
CASE 2
MusicVolume = MusicVolume + 1
IF MusicVolume > 4 THEN MusicVolume = 0
IF MusicVolume = 0 THEN SetVol% = 0
IF MusicVolume = 1 THEN SetVol% = 63
IF MusicVolume = 2 THEN SetVol% = 126
IF MusicVolume = 3 THEN SetVol% = 190
IF MusicVolume = 4 THEN SetVol% = 255
IF PlaySound = TRUE THEN setSoundVolume
CASE 3
IF pal$ = "NORMAL" THEN
pal$ = "BRIGHT"
AF2.InitPP256pal "Graphics/bright.pal" 
GOTO skipchoices:
END IF
IF pal$ = "BRIGHT" THEN
pal$ = "NORMAL"
AF2.InitPP256pal "Graphics/normal.pal" 
GOTO skipchoices:
END IF
CASE 4
IF GraphicMode = 1 THEN
GraphicMode = 2
ELSEIF GraphicMode = 2 THEN 
GraphicMode = 1
END IF
CASE 5
IF fpslimit = 33 THEN 
fpslimit = 25
ELSEIF fpslimit = 25 THEN
fpslimit = 33
END IF
CASE 6
EXIT SUB
END SELECT
END IF

skipchoices:

JoinScreen

workpage xor = 1

do 
loop until timer& - st >= (1/65) 
st = timer& 

SLEEP 1 

IF MULTIKEY(SC_ENTER) OR MULTIKEY(SC_UP) OR MULTIKEY(SC_DOWN) THEN GOTO skipkeyrestore3:
KeyFree = TRUE
skipkeyrestore3:

LOOP 

END SUB

SUB WriteHighScore
    
playStreamMusic("Sound/atmosphere.mp3")

' Some really dirty code for new top score
' inputting. It if the lowest score has 
' been exceeded and then calls the "input 
' new score" sub(InputName sub).
' Encryption codes HAVE BEEN CHANGED
' so don't try to use them to decrypt
' the default game scores.

' In case two players started the game
' we need to loop to this starting
' players value. Because, when one or
' the other player dies in two players
' mode numofplayers is switched to 1.
FOR countplayer = 1 TO startplayers

datafile$ = "data/hs.dat"
OPEN datafile$ FOR INPUT AS #3
FOR tar = 1 TO 8
INPUT #3, textarray(tar)
neoENCdepass SADD(textarray(tar)), LEN(textarray(tar)), "hi_mom!"
NEXT tar
CLOSE #3

FOR ar = 5 TO 8
ar2 = ar - 4
scores(ar2) = VAL(textarray(ar))
NEXT ar

' Check the top scores for this score
' (if it exceedes any score in it).
plscore = MainShip(countplayer).Score

' In two players mode if the first player has
' been destroyed all the values of the second
' player are passed onto the first player's
' variables and the second player continues
' playing as a single player.
' So when the second player gets destroyed or 
' finishes the game we need to check the right 
' scores. In this situation second player's 
' score is stored inside MainShip(1).Score
' while the first player's score is stored
' inside Player1OriginalScore variable, a
' stage before he got destroyed. Hope this
' wasn't confusing. scoreflag tells us
' if the first player got destroyed and
' the second continued playing.
IF startplayers = 2 AND scoreflag = 1 THEN
IF countplayer = 1 THEN plscore = Player1OriginalScore
IF countplayer = 2 THEN plscore =  MainShip(1).Score
END IF

IF plscore > scores(4) THEN

FOR nameloop = 1 TO 4
IF plscore > scores(nameloop) THEN

WHILE MULTIKEY(SC_Y)
WEND

DO
    
IF PlaySound = TRUE THEN FSOUND_Update 

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

DrawStars 1

zeross$ = ""
IF ABS(plscore)<10000 THEN zeross$ = "0"
IF ABS(plscore)<1000 THEN zeross$ = "00"
IF ABS(plscore)<100 THEN zeross$ = "000"
IF ABS(plscore)<10 THEN zeross$ = "0000"

IF startplayers = 2 THEN AF2.PP256fnt_brightness "PLAYER "+STR$(countplayer)+" FINAL SCORE: "+zeross$+STR$(plscore), 55, 98, 0, 32, Font1, GFX_v, GFX_h 
IF startplayers = 1 THEN AF2.PP256fnt_brightness "FINAL SCORE: "+zeross$+STR$(plscore), 90, 98, 0, 32, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "RECORD YOUR TOP SCORE(Y/N)?", 55, 115, 0, 42, Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240

IF MULTIKEY(SC_N) THEN 
BreakScreen
GOTO nextinputscore:
END IF

JoinScreen

workpage xor = 1

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

LOOP UNTIL MULTIKEY(SC_Y)

BreakScreen
InputName
highname$ = playername
startwrite = nameloop
GOTO writescore:
END IF
NEXT nameloop

writescore:
IF startwrite = 4 THEN GOTO writescore2:
FOR m = 3 TO startwrite STEP -1
n = m + 1
textarray(n) = textarray(m)
scores(n) = scores(m)
NEXT m
writescore2:
scores(startwrite) = plscore
textarray(startwrite) = highname$

FOR ar = 5 TO 8
ar2 = ar - 4
textarray(ar) = LTRIM$(STR$(scores(ar2)))
NEXT ar

OPEN datafile$ FOR OUTPUT AS #3
FOR tar = 1 TO 8
neoENCpass SADD(textarray(tar)), LEN(textarray(tar)), "hi_mom!"
PRINT #3, textarray(tar)
NEXT tar
CLOSE #3

' After a new score has been inputted display the
' high score tables.
IF (countplayer = 1 AND startplayers = 1) OR (countplayer = 2 AND startplayers = 2) THEN ReadHighScore

END IF

nextinputscore:
NEXT countplayer

END SUB

SUB DrawStars (smode)

' relsoft's 3D star projection routine from
' his 3D tutorials. Everything is the same but
' the changed color of the stars and ability
' to call the sub in two modes. The second
' mode moves the stars in positive y direction 
' too, which is only used in the end game
' animation.

' 
'///Move the stars
        '//Z=0 is 256 units away from the screen
        '//Adding values to Z moves the pixel towards us
        '//if Z > 256, the star is over our screen so reinitialize
        '//the stars Z value to 0(256 units away).
        FOR i = 0 TO UBOUND(Stars)
            Stars(i).z = Stars(i).z + Stars(i).zvel     'move it
            IF smode = 2 THEN
            Stars(i).y = Stars(i).y - Stars(i).zvel/2
            IF Stars(i).y < -60 THEN                'check for camera LENS
                Stars(i).y = 60                      'ReInit Z value
            END IF
            END IF
            
            IF Stars(i).z > 255 THEN                'check for camera LENS
                Stars(i).z = 0                      'ReInit Z value
            END IF

            sx! = Stars(i).x                        'StarX
            sy! = Stars(i).y                        'cleans the projectioon
            sz! = Stars(i).z                        'algo. ;*)
            Distance% = (LENS - sz!)                'get Distance
            IF Distance% THEN                       'if dist>0 then
                'Projection formula
                x% = XCENTER + (LENS * sx! / Distance%)
                y% = YCENTER - (LENS * sy! / Distance%)

            ELSE
                                        'do nothing
                                        'you wouldn't wan't to
                                        'divide by 0 would ya? :*)
            END IF
            clr% = sz!/24+164           ' modified sky blue color
                                        ' birghtness change according
                                        ' to the z distance(needs
                                        ' a gradient palette to work).
                                        'z=0 is the farthest
                                        'z=255 is the nearest
            PSET (x%, y%), clr%         'Draw each star

        NEXT i
    
END SUB

SUB neoENCdepass (Offsett AS ANY PTR, Lengthh&, passsword$)

' Subs used to encrypt and decrypt the high scores
' data.

   IF LEN(passsword$) = 0 THEN EXIT SUB
   nowpos% = 1

   FOR I& = 0 TO Lengthh& - 1
      Bytee% = PEEK(Offsett + I&)
      Bytee% = Bytee% - ASC(MID$(passsword$, nowpos%, 1))
      IF Bytee% < 0 THEN Bytee% = Bytee% + 256
      POKE Offsett + I&, Bytee%
      nowpos% = nowpos% + 1
      IF nowpos% > LEN(passsword$) THEN nowpos% = 1
   NEXT I&

END SUB

SUB neoENCpass (Offset AS ANY PTR, Length&, password$)
   IF LEN(password$) = 0 THEN EXIT SUB

   nowpos% = 1
   
   FOR I& = 0 TO Length& - 1
      Bytee% = PEEK(Offset + I&)
      Bytee% = Bytee% + ASC(MID$(password$, nowpos%, 1))
      IF Bytee% > 255 THEN Bytee% = Bytee% - 256
      POKE Offset + I&, Bytee%
      nowpos% = nowpos% + 1
      IF nowpos% > LEN(password$) THEN nowpos% = 1
   NEXT I&

END SUB

SUB ReadHighScore ()
    
' Nothing educational in this sub. It pastes the
' top scores table.

WHILE MULTIKEY(SC_ENTER)
WEND

datafile$ = "data/hs.dat"
OPEN datafile$ FOR INPUT AS #3
FOR tar = 1 TO 8
INPUT #3, textarray(tar)
neoENCdepass SADD(textarray(tar)), LEN(textarray(tar)), "hi_mom!"
NEXT tar
CLOSE #3
br = 30

DO
    
Frame2 = (Frame2 MOD 5) + 1

IF PlaySound = TRUE THEN FSOUND_Update 

br = br + 1
IF br > 45 THEN br = 30

screenset workpage, workpage xor 1

AF2.ClearScreen 0 

DrawStars 1

AF2.PP256fnt_brightness "TOP SCORES", 120, 50, 0, 42, Font1, GFX_v, GFX_h 

FOR tar = 1 TO 4
AF2.PP256fnt_brightness textarray(tar), 103, 70 + tar * 12, 0, br-(tar)*5, Font1, GFX_v, GFX_h 
NEXT tar
FOR ar = 5 TO 8
AF2.PP256fnt_brightness textarray(ar), 181, 70 + (ar - 4) * 12, 0, br-(ar-4)*5, Font1, GFX_v, GFX_h 
NEXT ar

AF2.PP256fnt_brightness "PRESS ENTER TO RETURN TO MAIN MENU", 24, 160, 0, 42, Font1, GFX_v, GFX_h 


AF2.Scale2x_320x240

JoinScreen

workpage xor = 1

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

LOOP UNTIL MULTIKEY(SC_ENTER)

BreakScreen

END SUB

SUB InputName ()
    
' The name inputting sub originally 
' made by Ryan Szrama. I found it useful 
' so might you.

' inputted name is stored in playername
' string and each letter in playerletter(letnum)
' strings.

WHILE INKEY$ <> "": WEND

' Reset the name to input and
' letters to input(might some
' be in memory from the
' last inputting.
playername=""
countlet=1
for playl=1 to 8
playerletter(playl)=""
next playl

DO ' Main inputting loop.

IF PlaySound = TRUE THEN FSOUND_Update 

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

DrawStars 1

blinker$=" "
Frame4 = (Frame4 mod 16) + 1
if Frame4>8 then blinker$="_"
a$ = INKEY$   

if asc(ucase$(a$)) >= 65 and asc(ucase$(a$)) <= 90 and countlet<9 then
playerletter(countlet) = UCASE$(a$)
countlet=countlet+1
end if
if asc(a$) = 8 and countlet > 1 then
countlet=countlet-1
playerletter(countlet) = ""
end if

playername=""
' Add each letter to the playername string.
for countpname=1 to 8
playername=playername+playerletter(countpname)
next countpname

AF2.PP256fnt_brightness "PLEASE ENTER YOUR NAME:", 68, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness playername+blinker$, 130, 80, 0, 42, Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240

JoinScreen

workpage xor = 1

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

' End name inputting when the player has
' clicked ENTER and at least one letter has been
' inputted.
LOOP UNTIL MULTIKEY(SC_ENTER) AND countlet>1

BreakScreen

END SUB

SUB Story ()
    
' The story sub, everything hard coded. It 
' could have been shorter if I used script 
' files. But why? :P
' Anway, nothing interesting in this sub.
    
countstory = 0

DO

IF PlaySound = TRUE THEN FSOUND_Update 

Frame2 = (Frame2 MOD 2) + 1

IF Frame2 = 2 THEN countstory = countstory + 1

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

curpic = 1
IF countstory < 100 THEN 
curpic = 1
stextline(1) = "In was a long journey for you, but you"
stextline(2) = "were eager to come home after 2 years"
stextline(3) = "of pilgrimage in the Scion Temples."
stextline(4) = ""
stextline(5) = ""
stextline(6) = ""
END IF
IF countstory > 99 AND countstory < 220 THEN 
curpic = 1
stextline(1) = "You missed your mother and father and"
stextline(2) = "the news of the Transvision technology"
stextline(3) = "changing the Republic made you only"
stextline(4) = "more restless in the seat of your"
stextline(5) = "faithful Aynar Claw."
stextline(6) = ""
END IF
IF countstory > 219 AND countstory < 340 THEN 
curpic = 2
stextline(1) = "In order to shorten your trip you"
stextline(2) = "decided to take your ship through the"
stextline(3) = "Black Passage. It was a well know fact"
stextline(4) = "that many ships disappeared while"
stextline(5) = "traveling through that sector, but you"
stextline(6) = "were too excited to think rationally."
END IF
IF countstory > 339 AND countstory < 470 THEN 
curpic = 3
stextline(1) = "Just in the heart of the region known"
stextline(2) = "as the Black Passage, a huge sky blue"
stextline(3) = "Vortex appeared in front of your ship"
stextline(4) = "and even before you had a chance to"
stextline(5) = "react, your ship was pulled inside."
stextline(6) = ""
END IF
IF countstory > 469 AND countstory < 570 THEN 
curpic = 4
stextline(1) = "Only few moments later, you were"
stextline(2) = "out of the Vortex but transported"
stextline(3) = "in a distant part of the universe,"
stextline(4) = "near an unknown star system."
stextline(5) = ""
stextline(6) = ""
END IF
IF countstory > 569 AND countstory < 670 THEN 
curpic = 4
stextline(1) = "You were surprised to discover that"
stextline(2) = "some strange force was effecting your"
stextline(3) = "ship and preventing you to leave the"
stextline(4) = "star system."
stextline(5) = ""
stextline(6) = ""
END IF
IF countstory > 669 AND countstory < 790 THEN 
curpic = 4
stextline(1) = "On the top of that, the system was"
stextline(2) = "filled with various alien space crafts,"
stextline(3) = "unwilling to communicate and only"
stextline(4) = "interested to scavenge the wreck"
stextline(5) = "of your ship."
stextline(6) = ""
END IF
IF countstory > 789 AND countstory < 890 THEN 
curpic = 4
stextline(1) = "You were left with no other choice"
stextline(2) = "but to fight for survival and hope you"
stextline(3) = "will find a way to escape this cage."
stextline(4) = "This STAR CAGE!"
stextline(5) = ""
stextline(6) = ""
END IF
IF countstory > 889 AND numofplayers = 2 THEN 
curpic = 5
stextline(1) = "Luckily, you discovered that another"
stextline(2) = "member of your race, who arrived there"
stextline(3) = "there only few hours before, was also"
stextline(4) = "trapped. Together, you might have"
stextline(5) = "better chances against the growing"
stextline(6) = "armada of alien ships."
END IF

IF numofplayers = 1 AND countstory = 889 THEN countstory = 1050

PUT (242,15), MiscBuffer2(curpic), PSET

FOR csline = 1 TO 6
AF2.PP256fntSP_tr.fadecust stextline(csline), 0, 120+csline*10, 0, 1, 0, Font1, GFX_v, GFX_h 
NEXT csline

AF2.PP256fntSP_tr.fadecust "ESC TO SKIP", 165, 225, 0, 0, 0, Font1, GFX_v, GFX_h 

GET (160,0)-(480,240), ScreenBuffer(1)
PUT (0,0), ScreenBuffer(1), PSET

AF2.Scale2x_320x240

JoinScreen

workpage xor = 1 

IF MULTIKEY(SC_F1) THEN
BSAVE "screenshot"+LTRIM$(RTRIM$(STR$(sshot)))+".bmp", 0, 307204
sshot=sshot+1
WHILE MULTIKEY(SC_F1)
WEND
END IF

do 
loop until timer& - st >= (1/22) 
st = timer& 

SLEEP 1
    
LOOP UNTIL MULTIKEY(SC_ESCAPE) OR countstory = 1050

BreakScreen

WHILE MULTIKEY(SC_ESCAPE)
SLEEP 1
WEND

END SUB

SUB PreStage5Anim ()

countstory = 0

DO

IF PlaySound = TRUE THEN FSOUND_Update 

Frame2 = (Frame2 MOD 2) + 1

IF Frame2 = 2 THEN countstory = countstory + 1

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

curpic = 6
IF countstory < 100 THEN 
curpic = 6
stextline(1) = "As your were traveling through the"
stextline(2) = "last vortex you noticed a strange"
stextline(3) = "source of energy in front of the"
stextline(4) = "ship, constantly moving forward."
stextline(5) = ""
stextline(6) = ""
END IF
IF countstory > 99 AND countstory < 220 THEN 
curpic = 6
stextline(1) = "Since you were desperate and tired"
stextline(2) = "of the constant battles and jumps"
stextline(3) = "into unknown, you decided to"
stextline(4) = "fire a projectile in the center"
stextline(5) = "of the vortex and hope for the best."
stextline(6) = ""
END IF
IF countstory > 219 AND countstory < 310 THEN 
curpic = 7
stextline(1) = "After a white flash you were back"
stextline(2) = "in normal space but apparently"
stextline(3) = "nowhere. Your location sensors"
stextline(4) = "were completely deaf."
stextline(5) = ""
stextline(6) = ""
END IF
IF countstory > 309 THEN 
curpic = 7
stextline(1) = "Only thing detectable by your sensors"
stextline(2) = "is a source of high energy just"
stextline(3) = "nearby, surrounded by several moving"
stextline(4) = "objects, probably space crafts."
stextline(5) = "They are not answering your hails."
stextline(6) = "This should be interesting."
END IF

PUT (242,15), MiscBuffer2(curpic), PSET

FOR csline = 1 TO 6
AF2.PP256fntSP_tr.fadecust stextline(csline), 0, 120+csline*10, 0, 1, 0, Font1, GFX_v, GFX_h 
NEXT csline

AF2.PP256fntSP_tr.fadecust "ESC TO SKIP", 165, 225, 0, 0, 0, Font1, GFX_v, GFX_h 

GET (160,0)-(480,240), ScreenBuffer(1)
PUT (0,0), ScreenBuffer(1), PSET

AF2.Scale2x_320x240

JoinScreen

workpage xor = 1 

do 
loop until timer& - st >= (1/22) 
st = timer& 

SLEEP 1
    
LOOP UNTIL MULTIKEY(SC_ESCAPE) OR countstory = 450

BreakScreen

WHILE MULTIKEY(SC_ESCAPE)
SLEEP 1
WEND
    
END SUB

SUB PlayAgainMenu ()

DO
    
IF PlaySound = TRUE THEN FSOUND_Update 

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

DrawStars 1

AF2.PP256fnt_brightness "PLAY AGAIN FROM STAGE 1(Y/N)?", 40, 55, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Your score won't be recorded", 34, 115, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "but you get to keep the", 34, 125, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "upgrades and reserve energy.", 34, 135, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Story cutscenes will be skipped", 34, 145, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "and the game will end only if", 34, 155, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "you get destroyed.", 34, 165, 0, 42, Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240

IF MULTIKEY(SC_N) THEN 
BreakScreen
EXIT SUB
END IF

JoinScreen

workpage xor = 1

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

LOOP UNTIL MULTIKEY(SC_Y)

PlayingAgain = TRUE

' Same code for switching from two players
' mode to single when one of the players
' gets destroyed that appears in 
' upgradeshipscreen sub.
IF numofplayers = 2 THEN
IF MainShip(2).Alive = FALSE THEN numofplayers = 1
IF MainShip(1).Alive = FALSE THEN
numofplayers = 1
Player1OriginalScore = MainShip(1).Score
MainShip(1).Shield = MainShip(2).Shield
MainShip(1).MaxShield = MainShip(2).MaxShield
MainShip(1).MaxReverse = MainShip(2).MaxReverse
MainShip(1).Acceleration = MainShip(2).Acceleration 
MainShip(1).MaxBattery = MainShip(2).MaxBattery
MainShip(1).WeaponLevel = MainShip(2).WeaponLevel 
MainShip(1).TurnLevel = MainShip(2).TurnLevel 
MainShip(1).StartSprite = MainShip(2).StartSprite
MainShip(1).Sprite = MainShip(2).Sprite
MainShip(1).WeaponPower = MainShip(2).WeaponPower
MainShip(1).Energy = MainShip(2).Energy
MainShip(1).Score = MainShip(2).Score
MainShip(1).Shots = MainShip(2).Shots
MainShip(1).ShipProj = MainShip(2).ShipProj
pseconds(1) = pseconds(2)
MainShip(1).Alive = TRUE
MainShip(2).Alive = FALSE
scoreflag = 1
END IF
END IF
    
END SUB


SUB Instructions ()

' A horrible and bloaty instructions
' code. Again, I could have made it
' much shorter if I placed all the 
' text in an extrnal file. Oh, well.

' Starting instructions page.
ipage = 1

DO
    
IF PlaySound = TRUE THEN FSOUND_Update 

screenset workpage, workpage xor 1
AF2.ClearScreen 0 

DrawStars 1

' If the user presses left or right change
' the page.
IF MULTIKEY(SC_LEFT) AND KeyFree = TRUE THEN 
KeyFree = FALSE
ipage = ipage - 1
IF ipage < 1 THEN ipage = 1
END IF
IF MULTIKEY(SC_RIGHT) AND KeyFree = TRUE THEN 
KeyFree = FALSE
ipage = ipage + 1
IF ipage > 12 THEN ipage = 12
END IF

' According to page display this or that
' text.
IF ipage = 1 THEN
AF2.PP256fnt_brightness "Use left/right arrow keys to navigate", 5, 10, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "through these instructions. Press", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "ESCAPE to exit them.", 5, 30, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "STAR CAGE is a top down space shooter", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "for one or two players simultaneously", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "(split screen mode).", 5, 80, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "It can be played in two game modes.", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "There is the main game mode with a", 5, 110, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "story, featuring 4 stages, plus a", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "boss stage.", 5, 130, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "In head on head mode you play against", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "another human player with a simple", 5, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "'destroy the opponent' objective.", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage = 2 THEN
AF2.PP256fnt_brightness "Rules of the Star Cage gameplay:", 5, 10, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "* camera follows the player's ship", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  (everything else is scrolled and", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  rotated!)", 5, 50, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "* no space inertia but the inertia", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  of the ship's engine", 5, 80, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "* circular play field(for example,", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  if you pass the bottom of the play ", 5, 110, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  field you will end up on its top)", 5, 120, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "* no ship to ship collision", 5, 140, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "* no friendly fire in story mode", 5, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  (your projectiles can't damage the", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  other player if you are playing", 5, 180, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "  in two players cooperative mode)", 5, 190, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage = 3 THEN
AF2.PP256fnt_brightness "CONTROLS", 5, 10, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Player 1:", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "UP ARROW KEY - forward engines", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "DOWN ARROW KEY - backward engines", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "LEFT ARROW KEY - rotate the ship", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "                 counter-clockwise", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "RIGHT ARROW KEY - rotate the ship", 5, 80, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "                  clockwise", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "ENTER - fire cannon(s)", 5, 100, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Player 2:", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "E - forward engines", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "D - backward engines", 5, 140, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "S - rotate the ship", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "    counter-clockwise", 5, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "F - rotate the ship clockwise", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Q - fire cannon(s)", 5, 180, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "ESC - abort game/pause", 5, 200, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=4 THEN
AF2.PP256fnt_brightness "In two players mode player 1 always", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "plays on the right side while", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "player 2 plays on the left side.", 5, 40, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "On the score screen and upgrades menu", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "each player uses HIS or HER keys to", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "navigate/confirm.", 5, 80, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "In story mode each stage is consisted", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "of three waves of enemies. After you", 5, 110, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "destroy all three waves a vortex will", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "appear near the sun(sky blue mark in", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the mini map). All you need to do is", 5, 140, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "to pass through this vortex.", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=5 THEN
AF2.PP256fnt_brightness "Some destroyed ships leave energy", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "modules. Be sure to collect all of", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "them since they are used to repair", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the shield and upgrade the ship", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "after every stage. A warning here.", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "The amount of energy modules is not", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "doubled in two players mode(although", 5, 80, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "there is more of them) so you will", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "have to learn to share.", 5, 100, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "After every stage you score will be", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "deducted by the number of seconds it", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "took you to complete it divided by", 5, 140, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "two, and by the number of shots you", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "fired divided by four. But, it will", 5, 160, 0, 42, Font1, GFX_v, GFX_h                 
AF2.PP256fnt_brightness "also be increased by your shield", 5, 170, 0, 42, Font1, GFX_v, GFX_h                 
AF2.PP256fnt_brightness "power times four.", 5, 180, 0, 42, Font1, GFX_v, GFX_h                 

END IF

IF ipage=6 THEN
AF2.PP256fnt_brightness "Your weapon is connected with the", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "weapon battery which prevents you", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "to hold fire constantly. If your", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "weapon battery completely depletes", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the ratio of your fire will be very", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "low. Weapon battery is recharged", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "quite fast but this feature will", 5, 80, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "count in longer attacks and will", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "force you to retreat, trust me.", 5, 100, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "The following is the list of", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "upgrades and their effect.", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=7 THEN
AF2.PP256fnt_brightness "Weapon upgrade: Every upgrade", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "results in another set of cannons.", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "A warning here. Your ship can carry", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "only 2 cannons. Front will be always", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "mounted so be sure that you want to,", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "for example, replace the back cannon", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "with side cannons. Every cannon", 5, 80, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "set will require different tactic", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "from you when attacking.", 5, 100, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Turning upgrade: With every upgrade", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "your turning speed will increase.", 5, 130, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Engine upgrade: This upgrade increases", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "ship's acceleration and maximum reverse.", 5, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "speed. Probably the least beneficial", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "upgrade.", 5, 180, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=8 THEN
AF2.PP256fnt_brightness "Shield upgrade: With this upgrade", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "you receive a new shield with new", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "and higher maximum hit value. Since", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "with this upgrade you are replacing", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the old shield with a new one you", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "will have 100% shield power!", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "This is very important for you to", 5, 80, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "know. Don't spend your reserve energy", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "on repairing the old shield if you", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "are just about to construct a new one.", 5, 110, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Battery upgrade: This upgrade makes", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "your battery to last longer in", 5, 140, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "full fire before depleting.", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=9 THEN
PUT (0,0), FullScreenBuffer(3), PSET
LINE (249,179)-(395,235),0,BF
AF2.PP256fnt_brightness "Your location relative", 5, 54, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "to the center of the map", 5, 64, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "(the sun is always near", 5, 74, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the center)", 5, 84, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "This is you(I just", 12, 139, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "want to be sure", 12, 149, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Baldrick gets it :P)", 12, 159, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "The mini map:", 190, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Red - enemies", 190, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Orange - planets", 190, 140, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Yellow - sun", 190, 150, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Green - you", 190, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Cyan - the other", 190, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "       player", 190, 180, 0, 42, Font1, GFX_v, GFX_h 

END IF

IF ipage=10 THEN
AF2.PP256fnt_brightness "How to play Star Cage?", 5, 20, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Using the map is imperative for a", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "success in this game. Use it to", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "position yourself toward an enemy and", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "on the critical distance, which is for", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "you to learn and discover, start", 5, 80, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "shooting and dodge, left or right. If", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "you miss, turn around and try to hit", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the enemy before it comes for", 5, 110, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "another attack. With faster", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "enemies it will become harder to get", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "behind them but that's why you have", 5, 140, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "upgrades.", 5, 150, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Standing still is not a way to win in", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "this game(it only works with one type", 5, 180, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "of enemy ships).", 5, 190, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=11 THEN
AF2.PP256fnt_brightness "Running in front of an enemy ship is", 5, 10, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "also not a way to win in this game.", 5, 20, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "Don't start dodging when the enemy is", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "right in front of you. You have to do", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "it sooner. Also, have in mind that", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "there are several kinds of behavior", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "of enemy ships in the game.", 5, 70, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Your ship is the fastest in the game", 5, 90, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "and use this to your advantage. Run", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "from groups of enemies that are too", 5, 110, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "wide and difficult to get behind. Run", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "and try again from another direction.", 5, 130, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Try to pickup every energy module. If", 5, 150, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "you have to leave one behind because", 5, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "it's in the heart of a large group of", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "enemies write down your location if", 5, 180, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "necessary. That's why you have the", 5, 190, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "pause/escape key.", 5, 200, 0, 42, Font1, GFX_v, GFX_h 
END IF

IF ipage=12 THEN
AF2.PP256fnt_brightness "How to play head on head?", 5, 10, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Since I didn't have anyone to play this", 5, 30, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "mode with I don't know how much it's", 5, 40, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "fun and playable. Just a note here", 5, 50, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "that destroying enemy ships is only", 5, 60, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "beneficial in the sense that some of", 5, 70, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "them drop energy modules.", 5, 80, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "Red energy modules repair your shield", 5, 100, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "while green energy modules give you", 5, 110, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "an upgrade(shield upgrades are not", 5, 120, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "included). Again, this only applies", 5, 130, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "on head on head mode.", 5, 140, 0, 42, Font1, GFX_v, GFX_h 

AF2.PP256fnt_brightness "In this mode there is no stages and", 5, 160, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "the game ends when one or both of the", 5, 170, 0, 42, Font1, GFX_v, GFX_h 
AF2.PP256fnt_brightness "players get destroyed.", 5, 180, 0, 42, Font1, GFX_v, GFX_h 
END IF

izero$=""
IF ipage<10 THEN izero$="0"
IF ipage<>9 THEN AF2.PP256fnt_brightness "Page "+izero$+STR$(ipage)+" of 12", 112, 228, 0, 42, Font1, GFX_v, GFX_h 

AF2.Scale2x_320x240   
IF ipage=9 THEN AF2.SprBlit_rotate.solid 560, 420, MiscBuffer2(9), 0

JoinScreen

workpage xor = 1

IF MULTIKEY(SC_F1) THEN
BSAVE "screenshot"+LTRIM$(RTRIM$(STR$(sshot)))+".bmp", 0, 307204
sshot=sshot+1
WHILE MULTIKEY(SC_F1)
WEND
END IF

do 
loop until timer& - st >= (1/33) 
st = timer& 

SLEEP 1

IF MULTIKEY(SC_RIGHT) OR MULTIKEY(SC_LEFT) THEN GOTO skipkeyrestinst:
KeyFree = TRUE
skipkeyrestinst:

LOOP UNTIL MULTIKEY(SC_ESCAPE)

BreakScreen

END SUB

SUB InitiateSparkle (spix!, spiy!, sangle!, spityp)
    
FOR initsparkle = 1 TO numofsparkles

' IF a sparkle is free initiate it.
IF Sparkle(initsparkle).Locked = FALSE THEN
' Keep its angle in proper boundaries.
IF sangle!<0 THEN sangle! = sangle! + 360
IF sangle!>359 THEN sangle! = sangle! - 360
Sparkle(initsparkle).X = spix!
Sparkle(initsparkle).Y = spiy!
Sparkle(initsparkle).Typ = spityp
Sparkle(initsparkle).Angle = sangle!
' The speed of a sparkle is partialy
' randomized which gives a better 
' effect.
ssprnd = (int(rnd * 12)+1)/10
Sparkle(initsparkle).Speed = 1+ssprnd
Sparkle(initsparkle).Locked = TRUE
' Sparkle life time(6 loops!).
Sparkle(initsparkle).LifeTime = 6
EXIT SUB    
END IF
 
NEXT initsparkle
    
END SUB

SUB SparkleLayer ()

' Sparkles are invisible particles(not drawn!)
' which spawn a type 4 explosion in every loop.
' In the current setup they last for 6 loops.
' Type 4 explosion consists of 3 frames and
' not 5, as it's the case with other
' explosions.
FOR csparkle = 1 TO numofsparkles

IF Sparkle(csparkle).Locked = TRUE THEN

Sparkle(csparkle).LifeTime = Sparkle(csparkle).LifeTime - 1
IF Sparkle(csparkle).LifeTime<0 THEN Sparkle(csparkle).Locked = FALSE

radspangle! = (Sparkle(csparkle).Angle* 3.14159)/180
Sparkle(csparkle).X = Sparkle(csparkle).X + Sparkle(csparkle).Speed * SIN(radspangle!)
Sparkle(csparkle).Y = Sparkle(csparkle).Y - Sparkle(csparkle).Speed * COS(radspangle!)

IF Sparkle(csparkle).Typ = 1 THEN
InitiateExplosion Sparkle(csparkle).X-5, Sparkle(csparkle).Y-5, 4, 5   
END IF

END IF
    
NEXT csparkle
    
END SUB

SUB Intro ()
    
BLOAD "Graphics/LOGO.BMP"    
GET (207,36)-(435,75), MiniMapBuffer(1)    
GET (180,366)-(460,386), MiniMapBuffer(2)  
FOR cline = 1 TO 90 STEP 2
LINE (0,(cline*2)+93)-(640,1+(cline*2)+93), 0, BF    
NEXT cline
GET (50,95)-(590,269), ScreenBuffer(1) 
BLOAD "Graphics/LOGO.BMP" 
FOR cline = 0 TO 90 STEP 2
LINE (0,(cline*2)+93)-(640,1+(cline*2)+93), 0, BF    
NEXT cline
GET (50,95)-(590,269), ScreenBuffer(2) 

CLS
ymov1=-60
ymov2=490
xmov=0
xinertia=5
xlimit=610
xdirec = 1
xinertiamax = 5
countend = 0

DO

IF PlaySound = TRUE THEN FSOUND_Update 

screenset workpage, workpage xor 1
AF2.ClearScreen 0

ymov1=ymov1+2
IF ymov1>35 THEN ymov1=35

IF xinertiamax=1 AND xmov=590 THEN 
ymov2=ymov2-2
IF ymov2<320 THEN 
ymov2=320
countend = countend + 1
END IF
END IF

IF ymov1=35 THEN
IF xinertiamax>1 OR xmov<>590 THEN
IF xdirec = 1 AND xinertia<xinertiamax THEN xinertia=xinertia+0.9
IF xdirec = -1 AND xinertia>-xinertiamax THEN xinertia=xinertia-0.9
xmov=xmov+xinertia
IF xmov>xlimit AND xdirec = 1 THEN 
xdirec = -1
IF xinertiamax>1 THEN xinertiamax=xinertiamax-1
END IF
IF xmov<xlimit-40 AND xdirec = -1 THEN 
xdirec = 1
IF xinertiamax>1 THEN xinertiamax=xinertiamax-1
END IF
END IF
END IF

PUT (207, ymov1), MiniMapBuffer(1), PSET
PUT (180, ymov2), MiniMapBuffer(2), PSET

PUT (xmov-540, 95), ScreenBuffer(1), TRANS
PUT (640-xmov, 95), ScreenBuffer(2), TRANS

workpage xor = 1

do 
loop until timer& - st >= (1/60) 
st = timer& 

SLEEP 1

LOOP UNTIL countend > 90 

BreakScreen

END SUB