
#define ALLEGRO_STATICLINK

#ifdef ALLEGRO_WINDOWS
#define AMOTH_WINDOWS
#endif

#if defined (ALLEGRO_LINUX) || defined(ALLEGRO_UNIX)
#define AMOTH_LINUX
#endif

#ifdef ALLEGRO_MACOSX
#define AMOTH_MAC
#endif


#define NO_KEYS CKEY_END
#define X_MIN 10000
#define Y_MIN 20000
#define X_MAX 315000
#define Y_MAX 468000
#define X_MIDDLE 200000
#define Y_MIDDLE 240000

#define RAND_X grand(X_MAX - (X_MIN * 4)) + X_MIN * 2
#define RAND_Y grand(Y_MAX - (Y_MIN * 4)) + Y_MIN * 2

//#define SANITY_CHECK

#define SMALL_ROTATIONS 128
#define SMALL_ROTATIONS_ANGLE 8
// number of different angles bullets can appear in

#define GRAIN 1000

#define MAX_SCORE 9999999

#define ANGLEFULL_HEX 0x400
#define ANGLE_1 1024
#define ANGLE_2 512
#define ANGLE_3 341
// 3 is not exact
#define ANGLE_4 256
#define ANGLE_5 205
// not exact
#define ANGLE_6 171
// 6 is not exact
#define ANGLE_8 128
#define ANGLE_10 102
#define ANGLE_16 64
#define ANGLE_8_3 384
#define ANGLE_16_3 192
#define ANGLE_32 32
#define ANGLE_64 16
#define ANGLE_128 8
#define ANGLE_TO_FIXED 4

#ifndef PI
#define PI 3.141592
#endif

#define NO_ENEMIES 50
#define NO_PBULLETS 100
#define NO_EBULLETS 500
#define NO_CLOUDS 150
#define NO_SEEKERS 24
// should be plenty
#define SEEKER_ENERGY 100

#define MAX_TARGETS 40
/*
enum
{
POLE_NONE,
POLE_WHITE,
POLE_BLACK,
POLE_BOTH,
POLE_RANDOM
};*/

enum
{
PBULLET_NONE,
PBULLET_BASIC,
PBULLET_WAVE,
PBULLET_HEAVY,
PBULLET_MULTI1,
PBULLET_MULTI2,
PBULLET_MULTI3,
PBULLET_MULTI4,
PBULLET_MULTI5,
PBULLET_CIRCLE,
PBULLET_BLAST,
PBULLET_TURRET,
PBULLET_WHITE2,
PBULLET_GREEN2,
PBULLET_GREEN2_VORTEX

};

enum
{
EBULLET_NONE,
EBULLET_BALL,
EBULLET_SHOT,
EBULLET_SPIN,
EBULLET_SHOT2,
EBULLET_SHOT3,
EBULLET_FAT_SHOT,
EBULLET_FATTER_SHOT,
EBULLET_BEAM1,

EBULLET_TRIANGLE,
EBULLET_DIAMOND,
EBULLET_STAR,
EBULLET_CIRCLE


};

struct optionstruct
{
 int sound_init; // if 0, sound isn't initialised at all. Changed in config file only.
 int sound_mode; // mono, stereo, reversed, off
 int run_vsync; // on or off
 int sound_volume; // sound fx volume; if 0 sound effects not played
 int ambience_volume; // if 0 ambience not played

 int highscore [3];
// int unlock_purple;
// int unlock_void;
// int unlock_god;
// int colour_text;
};

struct gamestruct
{
 int users;
 int single_player;
};

struct arenastruct
{
  int level;
  int difficulty;

  int level_finished;
  int game_over;
  int new_level_sign;
  int player_lives;
  int players;

  int underlay_position;
  int underlay2_position;

  int underlay_position2;
  int underlay2_position2;

  unsigned char counter;

  int beam;
  int old_beam;

  int starting_level;
  int just_got_highscore;

};



enum
{
CMD_LEFT,
CMD_RIGHT,
CMD_UP,
CMD_DOWN,
CMD_UPLEFT,
CMD_UPRIGHT,
CMD_DOWNLEFT,
CMD_DOWNRIGHT,
CMD_FIRE,
CMD_SWITCH,
CMD_CHARGE,
CMD_END
};

#define NO_CMDS CMD_END

enum
{
CKEY_LEFT,
CKEY_RIGHT,
CKEY_UP,
CKEY_DOWN,
CKEY_FIRE,
CKEY_SWITCH,
CKEY_CHARGE,
CKEY_AUTOFIRE,
CKEY_END

};

struct playerstruct
{

// char player_cmd [NO_CMDS];

 int score;

 int key [NO_KEYS];
 int cmds [NO_CMDS];
 int controller;
 char in_play; // in the game currently
 int playing; // playing (may be in respawn or eliminated and waiting for an extend)
 int x, y, x_speed, y_speed;
 int recycle;
 int recycle2;
 int pole;
 int switch_recycle;
 int switching;
 int sides;
 int charge;
 int autofire;
 int autofire_toggle;

 int power [2];
 int weapon [2];

 int red_fire;
 int blue_fire;
 int blue_was_firing;
 int white_recycle1;
 int white_recycle2;
 int green_side;

 int blue2_fire;

 int bank;
 int energy;

 int respawning;
 int grace;

};


struct enemystruct
{
 int type;
 int x;
 int y;
 int x_speed;
 int y_speed;
 int pole;
 int hp;
 int angle1;
 int angle2;
 int angle3;
 int angle1_turning;
 int angle1_turning_count;
 int persistent;
 int recycle;
 int burst_recycle;
 int turn_direction;

 int a1, b1, c1, d1;

 int x2;
 int y2;

 int x_target [MAX_TARGETS];
 int y_target [MAX_TARGETS];
 int target_time;
 int max_target_time;
 int target;

 int hurt_pulse;

 int distance; // used in calculating seeker locks
};


struct bossstruct
{
  int hp;
  int max_hp;
  int arm1;
  int arm1_change;
  int arm2;
  int arm2_change;
  int moving;
  int e1;
  int e2;
  int fight;
  int move_x;
  int move_y;
  int move_time;

  int bpattern;
  int btime;
  int brecycle;
  int bstatus1;
  int bstatus2;

  int pulse;

  int arm_colour;
  int arm_change;
  int arm_recycle;
  int arm_beam;
  int arm_beam_side;
  int arm_beam_angle [4];

  int exploding;

// mb2
  int side1;
  int side2;
  int old_angle [10];
  int spot_angle;
  int spot_angle_inc;
  int spot_angle_inc_inc;
  int bpattern2;
  int new_bpattern;
  int new_bpattern2;

// boss2
  int size;
  int phase;
  int phase_count;
  int size_inc;
  int colour;
  int bflower_recycle;

// mb1
  int angle_1;
  int angle_2;
  int angle_3;
  int trecycle;

};

enum
{
    BOSS1_FIRE_NONE,
    BOSS1_FIRE_CIRCLES,
    BOSS1_FIRE_SCATTER,
    BOSS1_FIRE_SPIRAL,
    BOSS1_FIRE_BURST
};

enum
{
    BOSS1_APPROACH,
    BOSS1_OPEN,
    BOSS1_HOLD,
    BOSS1_SIDES,
    BOSS1_SWIRL,
    BOSS1_DART,
    BOSS1_BEAM1,
    BOSS1_BEAM2,
    BOSS1_SWIRL2
};



#define NO_PICKUPS 4

struct pickupstruct
{
 int colour;
 int exists;
 int x;
 int y;
};

enum
{
ENEMY_NONE,
ENEMY_TWISTER,
ENEMY_DIVER,
ENEMY_GLIDER1,
ENEMY_MARCHER1,
ENEMY_ATTACKER1,
ENEMY_ATTACKER2,
ENEMY_ATTACKER3,
ENEMY_BEAMER1,
ENEMY_BASIC1,
ENEMY_SHOTTER1,
ENEMY_ZAPPER1,
ENEMY_DIPPER1,
ENEMY_DIPPER2,
ENEMY_BASIC2,
ENEMY_BASIC3,
ENEMY_CARRIER,
ENEMY_BURSTER,
ENEMY_BOSS1,

ENEMY_CROSS,
ENEMY_FLOWER1,
ENEMY_FLOWER2,
ENEMY_FLOWER3,
ENEMY_FLOWER4,
ENEMY_FLOWER5,
ENEMY_CROSS2,
ENEMY_WINGS,
ENEMY_MB2,

ENEMY_CARRIER2,

ENEMY_BOSS2,
ENEMY_BFLOWER,
ENEMY_MB1,
ENEMY_BFIGHTER,
//ENEMY_BASIC3,
NO_ENEMY_TYPES

};

#define GLIDER_Y_ADJUST 20
#define SHOTTER1_Y_ADJUST 15

enum
{
AI_DIVER,
AI_FALL,
AI_DANCER,
AI_GLIDER,
AI_MARCH,
AI_ATTACKER,
AI_BEAMER,
AI_PAUSER,
AI_BOSS1,
AI_MB2,
AI_BOSS2,
AI_BFLOWER,
AI_MB1,
AI_BFIGHTER,


};

struct eclassstruct
{
 int max_hp;
 int size;
 int ai;
 int speed1;
 int speed2;
 int speed3;
 int score;

// int speed;


};

enum
{
BULLET_NONE,
BULLET_BLOB

};

enum
{
CLOUD_NONE,
CLOUD_SHOCKWAVE,
CLOUD_EXPLODE,
CLOUD_SLOW_EXPLODE, // same as explode, but shrinks more slowly
CLOUD_SPRAY,
CLOUD_DRAG_EXPLODE, // slow explodes with drag
CLOUD_SEEKER_TRAIL,
CLOUD_LARGE_SHOCKWAVE,
CLOUD_LARGE_SPRAY,
CLOUD_DELAY_EXPLODE,
CLOUD_SPAWNER,
CLOUD_BLUE_WAVE,
CLOUD_GREEN_WAVE,
CLOUD_RED_WAVE,
CLOUD_PURPLE_WAVE,
CLOUD_GREEN_RING,
CLOUD_TURRET_TRAIL,
CLOUD_ZAP,
CLOUD_GREEN2_RING,
CLOUD_SHOCKWAVE2,
CLOUD_LARGE_SHOCKWAVE2,
CLOUD_EXPLODE2


};

enum
{
  WPN_RED,
  WPN_BLUE,
  WPN_GREEN,
  WPN_WHITE
};

struct pbulletstruct
{
 int type;
 int x;
 int y;
 int type2;
 int type3;
 int timeout;
 int xsize;
 int ysize;
 int x_speed; // only used for some bullets - eg multi
 int y_speed;
};

struct seekerstruct
{
// int type;
 int active;
 int x;
 int y;
 int angle;
 int x_speed;
 int y_speed;
 int target;
 int player;
 int pole;
 int timeout;
 int acceleration;
 int drag;
 int turn;
};

struct ebulletstruct
{
 int type;
 int x;
 int y;
 int x_speed;
 int y_speed;
 int pole;
 int energy_value;
 int angle;
 int turn_direction;
 int timeout;
 int status;
 int status2;
 int status3;
 int x2;
 int y2;
};


struct cloudstruct
{
 int type;
 int x;
 int y;
 int x2;
 int y2;
 int x_speed;
 int y_speed;
 int type2;
 int timeout;
 int angle;
 int delay;
};
