/*
Overgod
Copyright (C) 2005 Linley Henzell

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public Licence as published by
    the Free Software Foundation; either version 2 of the Licence, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public Licence for more details.

    You should have received a copy of the GNU General Public Licence
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    The GPL version 2 is included in this distribution in a file called
    LICENCE.TXT. Use any text editor or the TYPE command to read it.

    You should be able to reach me by sending an email to
    l_henzell@yahoo.com.au.

File: sound.c
History:
11/9/2005 - Version 1.0 finalised

This file contains:
 - sound initialisation and playing.
enums in sound.h

*/

#include "config.h"

#include "allegro.h"

#include <string.h>

#include "sound.h"

#include "globvars.h"

#include "math.h"
#include "stuff.h"

//int debug_sound [5];


enum
{
NOTE_0C,
NOTE_0CS,
NOTE_0D,
NOTE_0DS,
NOTE_0E,
NOTE_0F,
NOTE_0FS,
NOTE_0G,
NOTE_0GS,
NOTE_0A,
NOTE_0AS,
NOTE_0B,
NOTE_1C,
NOTE_1CS,
NOTE_1D,
NOTE_1DS,
NOTE_1E,
NOTE_1F,
NOTE_1FS,
NOTE_1G,
NOTE_1GS,
NOTE_1A,
NOTE_1AS,
NOTE_1B,
NOTE_2C,
NOTE_2CS,
NOTE_2D,
NOTE_2DS,
NOTE_2E,
NOTE_2F,
NOTE_2FS,
NOTE_2G,
NOTE_2GS,
NOTE_2A,
NOTE_2AS,
NOTE_2B,
NOTE_3C,
NOTE_3CS,
NOTE_3D,
NOTE_3DS,
NOTE_3E,
NOTE_3F,
NOTE_3FS,
NOTE_3G,
NOTE_3GS,
NOTE_3A,
NOTE_3AS,
NOTE_3B,
NOTE_ENDNOTE

};

#define L_1 16
#define L_2 8
#define L_3 6
#define L_4 4
#define L_8 2

#define PAN_LEFT 64
#define PAN_CENTRE 127
#define PAN_RIGHT 192

enum
{
BEAT_START,
BEAT_BOOM,
BEAT_SNARE,
BEAT_TOM,
BEAT_DRUM,
NO_BEATS,
BEAT_WAIT,
BEAT_EMPTY
};


// TO DO!!! Make sure display collision detection is always run!!! It isn't now!!

int music [13] [51] [4] =
{
 {
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1G, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1G, L_3, PAN_CENTRE - 40},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_1DS, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1DS, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1AS, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1DS, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_1D, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1D, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1D, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1A, L_3, PAN_CENTRE - 40},
  {BEAT_START, NOTE_2D, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1D, L_1 - 1, PAN_CENTRE},
/*
{BEAT_START, NOTE_1D, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1E, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1F, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1G, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1A, L_1, PAN_LEFT},
{BEAT_START, NOTE_1B, L_1, PAN_RIGHT},
{BEAT_START, NOTE_2C, L_1, PAN_RIGHT},*/
  {BEAT_EMPTY, 0, 0}// loop
 },

 {
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1G, L_3, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2G, L_1, PAN_CENTRE},

/*  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2G, L_3, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_1, PAN_CENTRE},*/

  {BEAT_START, NOTE_2C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_3, PAN_CENTRE},
  {BEAT_START, NOTE_2G, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_2DS, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2G, L_3, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_1 - 1, PAN_CENTRE},

  {BEAT_START, NOTE_2DS, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2D, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2CS, L_1 - 2, PAN_CENTRE},
/*
{BEAT_START, NOTE_1D, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1E, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1F, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1G, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1A, L_1, PAN_LEFT},
{BEAT_START, NOTE_1B, L_1, PAN_RIGHT},
{BEAT_START, NOTE_2C, L_1, PAN_RIGHT},*/
  {BEAT_EMPTY, 0, 0}// loop
 },


 {
  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1G, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1G, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1DS, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1DS, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1AS, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},

  {BEAT_BOOM, NOTE_1D, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1D, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1D, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1A, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_2D, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1D, L_1 - 1, PAN_CENTRE},
  {BEAT_EMPTY, 0, 0}// loop
 },

 {
  {BEAT_DRUM, NOTE_1C, L_1 + L_1, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 + L_1 - 2, PAN_CENTRE},

  {BEAT_DRUM, NOTE_1C, L_1 + L_1, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 + L_1 - 2, PAN_CENTRE},

  {BEAT_DRUM, NOTE_1C, L_1 + L_1, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 + L_1 - 2, PAN_CENTRE},

  {BEAT_DRUM, NOTE_1C, L_1 + L_1, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 + L_1 - 2, PAN_CENTRE},


  {BEAT_EMPTY, 0, 0, 0}// loop
 },

 {
/*  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE},
  {BEAT_TOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_TOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE},
  {BEAT_TOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_TOM, NOTE_1C, L_2, PAN_CENTRE},*/

  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE - 50},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE + 50 },
  {BEAT_DRUM, NOTE_2C, L_1, PAN_CENTRE},

  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE - 50},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE + 50},
  {BEAT_DRUM, NOTE_2C, L_1, PAN_CENTRE},

  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE - 50},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE + 50},
  {BEAT_DRUM, NOTE_2C, L_1, PAN_CENTRE},

  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE - 50},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_DRUM, NOTE_1C, L_1 - 1, PAN_CENTRE + 50},
  {BEAT_DRUM, NOTE_2C, L_1, PAN_CENTRE},


  {BEAT_EMPTY, 0, 0, 0}// loop
 },

 {
  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1G, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1G, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1C, L_1, PAN_CENTRE},
// total = 62

  {BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1DS, L_1 - 1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1DS, L_1 - 1, PAN_CENTRE},

  {BEAT_BOOM, NOTE_1D, L_1, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1D, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1CS, L_3, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1CS, L_2, PAN_CENTRE},
  {BEAT_BOOM, NOTE_1CS, L_2 + 16 - 1, PAN_CENTRE},

  {BEAT_EMPTY, 0, 0, 0}// loop
 },

 {
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1C, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1G, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_2C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1G, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_2G, L_3, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1G, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_2DS, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_2AS, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_2DS, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_2AS, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1DS, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_2D, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_2D, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1A, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_2D, L_3, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1A, L_2, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1D, L_1 - 1, PAN_CENTRE},

  {BEAT_EMPTY, 0, 0, 0}// loop

 },


 {
  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1G, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1A, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1DS, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1F, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1D, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1G, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1A, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1DS, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1F, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1D, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1G, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1A, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1DS, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1F, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1D, L_1, PAN_CENTRE},

  {BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
  {BEAT_START, NOTE_1G, L_2, PAN_CENTRE},
  {BEAT_START, NOTE_1A, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1DS, L_3, PAN_CENTRE + 40},
  {BEAT_START, NOTE_1F, L_2, PAN_CENTRE - 40},
  {BEAT_START, NOTE_1D, L_1, PAN_CENTRE},

  {BEAT_EMPTY, 0, 0, 0}// loop

 },

 {
  {BEAT_WAIT, 0, 36, 0},// loop
  {BEAT_EMPTY, 0, 0, 0}// loop
 }
};
/*
int boom [51] [4] =
{
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1G, L_3, PAN_RIGHT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},

{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1G, L_3, PAN_RIGHT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},
// total = 62

{BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1DS, L_1 - 1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1DS, L_1 - 1, PAN_CENTRE},

{BEAT_BOOM, NOTE_1D, L_1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1D, L_2, PAN_CENTRE},
{BEAT_BOOM, NOTE_1CS, L_3, PAN_LEFT},
{BEAT_BOOM, NOTE_1CS, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1CS, L_2 + 16, PAN_LEFT},

{BEAT_EMPTY, 0, 0}// loop
*/
/*
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},

{BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1G, L_3, PAN_CENTRE},
{BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
*/

//};


/*
int music [51] [4] =
{
{BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1G, L_3, PAN_CENTRE},
{BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_1, PAN_CENTRE},

{BEAT_START, NOTE_1C, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1G, L_3, PAN_CENTRE},
{BEAT_START, NOTE_2C, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1C, L_1, PAN_CENTRE},

{BEAT_START, NOTE_1DS, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1DS, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1DS, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1AS, L_3, PAN_CENTRE},
{BEAT_START, NOTE_2DS, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1DS, L_1, PAN_CENTRE},

{BEAT_START, NOTE_1D, L_1, PAN_CENTRE},
{BEAT_START, NOTE_1D, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1D, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1A, L_3, PAN_CENTRE},
{BEAT_START, NOTE_2D, L_2, PAN_CENTRE},
{BEAT_START, NOTE_1D, L_1, PAN_CENTRE},
{BEAT_EMPTY, 0, 0}// loop

};

int boom [51] [4] =
{
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1G, L_3, PAN_RIGHT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},

{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1G, L_3, PAN_RIGHT},
{BEAT_BOOM, NOTE_1C, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1C, L_1, PAN_LEFT},
// total = 62

{BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1DS, L_1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1DS, L_1 - 1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1DS, L_1 - 1, PAN_CENTRE},

{BEAT_BOOM, NOTE_1D, L_1, PAN_CENTRE},
{BEAT_BOOM, NOTE_1D, L_2, PAN_CENTRE},
{BEAT_BOOM, NOTE_1CS, L_3, PAN_LEFT},
{BEAT_BOOM, NOTE_1CS, L_2, PAN_LEFT},
{BEAT_BOOM, NOTE_1CS, L_2 + 16, PAN_LEFT},

{BEAT_EMPTY, 0, 0}// loop


};
*/

enum
{
MUSIC_BASIC,
MUSIC_START2,
MUSIC_BOOM,
MUSIC_SNARE,
MUSIC_SNARE2,
MUSIC_BOOM2,
MUSIC_START3,
MUSIC_START4,
MUSIC_WAIT,
MUSIC_EMPTY,
MUSIC_END
};

// music, repeats, tone offset, pan offset, vol offset
int overmusic [51] [4] [5] =
{
 {
  {MUSIC_WAIT, 1, 0, 0, 0},
  {MUSIC_EMPTY, 1, 13, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },
/* {
  {MUSIC_SNARE, 1, 20, 0, 100},
  {MUSIC_EMPTY, 1, 13, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },
 {
  {MUSIC_SNARE2, 1, 20, 0, 100},
  {MUSIC_EMPTY, 1, 13, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },*/
 {
  {MUSIC_BOOM, 1, 20, 0, 150},
  {MUSIC_SNARE2, 1, 20, 0, 100},
  {MUSIC_EMPTY, 0, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },
/*
 {
  {MUSIC_END, 1, 0, 0, 0},
  {MUSIC_BOOM, 1, 26, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0}
 },*/


 {
  {MUSIC_BOOM, 1, 20, 0, 150},
  {MUSIC_SNARE2, 1, 20, 0, 100},
  {MUSIC_EMPTY, 0, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },
 {
  {MUSIC_BASIC, 1, 0, 0, - 40},
  {MUSIC_EMPTY, 1, 13, 0, 100},
  {MUSIC_EMPTY, 1, 20, 0, 100},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },
 {
  {MUSIC_BASIC, 1, 0, 0, - 40},
  {MUSIC_BOOM, 1, 13, 0, 100},
  {MUSIC_SNARE2, 1, 20, 0, 100},
  {MUSIC_EMPTY, 0, 0, 0, 0}
 },
 {
  {MUSIC_START2, 1, 0, 0, -40},
  {MUSIC_BOOM, 1, 20, 0, 100},
  {MUSIC_SNARE2, 1, 20, 0, 100},
  {MUSIC_EMPTY, 0, 0, 0}
 },
 {
  {MUSIC_END, 1, 0, 0, 0},
  {MUSIC_BOOM, 1, 26, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0},
  {MUSIC_EMPTY, 0, 0, 0}
 },

};

int overposition;
int finished_overpositions;

int random_tone;

int mtrack_position [4];
int mtrack_count [4];
int mtrack_music [4];
int mtrack_volume [4];
int mtrack_tone_offset [4];
int mtrack_force_beat [4];
int mtrack_glitchy [4];

int random_track_length;
//int boomtrack_position;
//int boomtrack_count;

int success_note [3];
int success_samp;
int success_step;
int success_base;

#define NO_TONES 56
#define BASE_TONE 200

int tone [NO_TONES];



extern struct optionstruct options;

SAMPLE *new_sounds [NO_NWAVS];

SAMPLE *beat [NO_BEATS];

char sound_active;

void check_sound(SAMPLE *samp);
void load_sample_in(int samp, const char *sfile);
void load_new_sample_in(int samp, const char *sfile);
void load_new_ambi_in(int samp, const char *sfile);
void make_random_mtrack(void);

void play_success_sound(void);



void init_sound(void)
{
#ifdef SOUND_OFF
 return;
#endif

//set_config_int("Misc", "EffectVolume", 100);
//set_config_int("Misc", "SoundInit", 1);

//set_config_int("Misc", "MusicVolume", 100);
//set_config_int("Misc", "StereoMode", SOUNDMODE_STEREO);

   options.sound_volume = get_config_int("Misc", "EffectVolume", 100);
   options.ambience_volume = get_config_int("Misc", "MusicVolume", 100);
   options.sound_init = get_config_int("Misc", "SoundInit", 1);
   options.sound_mode = get_config_int("Misc", "StereoMode", SOUNDMODE_STEREO);

   if (options.sound_volume > 100)
    options.sound_volume = 100;
   if (options.sound_volume < 0)
    options.sound_volume = 0;

   if (options.ambience_volume > 100)
    options.ambience_volume = 100;
   if (options.ambience_volume < 0)
    options.ambience_volume = 0;

   int i, j;
   float t;

   for (i = 0; i < NO_TONES; i ++)
   {
    t = (float) BASE_TONE;
    for (j = 0; j < i; j ++)
    {
     t *= (float) 1.059463094359;//(1000 + (1000 / 18)) / 1000;
    }
    tone [i] = t;
    // saves me from having to remember how to use the pow function
   }

   sound_active = 1;

   if (options.sound_init == 0)
   {
    sound_active = 0;
    return;
   }

   reserve_voices(16, 0);
   if (install_sound (DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) == -1)
   {
    sound_active = 0;
   }
   set_volume(255, 0);

   load_new_sample_in(NWAV_BANG, "bang");
   load_new_sample_in(NWAV_BIGBANG, "bigbang");
   load_new_sample_in(NWAV_FIRE, "fire");
   load_new_sample_in(NWAV_FIRE2, "fire2");
   load_new_sample_in(NWAV_BLAST, "blast");
   load_new_sample_in(NWAV_ZAP, "zap");
   load_new_sample_in(NWAV_BEAM1, "beam1");
   load_new_sample_in(NWAV_BEAM2, "beam2");
   load_new_sample_in(NWAV_CIRCLE, "circle");
   load_new_sample_in(NWAV_PBEAM2, "pbeam2");
   load_new_sample_in(NWAV_PBEAM1, "pbeam1");
   load_new_sample_in(NWAV_SHOT, "shot");
   load_new_sample_in(NWAV_POP, "pop");
   load_new_sample_in(NWAV_BLIP, "blip");
   load_new_sample_in(NWAV_BLIP2, "blip2");
   load_new_sample_in(NWAV_TAP, "tap");
   load_new_sample_in(NWAV_TONE, "tone");
   load_new_sample_in(NWAV_BLAST2, "blast2");
   load_new_sample_in(NWAV_BEAM3, "beam3");
   load_new_sample_in(NWAV_WAVE, "wave");
   load_new_sample_in(NWAV_POWERUP, "powerup");
   load_new_sample_in(NWAV_BLOP, "blop"); // boss2 swap


    load_new_ambi_in(BEAT_START, "start");
    load_new_ambi_in(BEAT_BOOM, "boom");
    load_new_ambi_in(BEAT_SNARE, "snare");
    load_new_ambi_in(BEAT_TOM, "tom");
    load_new_ambi_in(BEAT_DRUM, "drum");


}

void init_mtracks(void)
{

 overposition = 0;
 finished_overpositions = 0;
 random_tone = 0;
 random_track_length = 1 + grand(3);
 int i;

 for (i = 0; i < 4; i ++)
 {
  mtrack_position [i] = 0;
  mtrack_count [i] = 10;
  mtrack_music [i] = MUSIC_WAIT;
  mtrack_force_beat [i] = -1;
  mtrack_glitchy [i] = 0;
 }
/* mtrack_position = 0;
 mtrack_count = 10;
 boomtrack_position = 0;
 boomtrack_count = 10;*/

}



void run_mtracks()
{
 int i, j;

 if (sound_active == 0 || options.ambience_volume == 0) return;

 for (i = 0; i < 4; i ++)
 {
  if (!finished_overpositions && overmusic [overposition] [i] [0] == MUSIC_EMPTY)
   continue; // can't have all four being empty

  if (finished_overpositions && mtrack_music [i] == MUSIC_EMPTY)
   continue; // can't have all four being empty


  mtrack_count [i] --;

   if (i == 0 && mtrack_count [i] <= 0 && music [mtrack_music [0]] [mtrack_position [i]] [0] == BEAT_EMPTY)
   {
    if (finished_overpositions)
    {
      make_random_mtrack();
      return;
    }
     else
     {
      overposition ++;
      if (overmusic [overposition] [0] [0] == MUSIC_END)
      {
       overposition = 0;
       finished_overpositions = 1;
       return;
       // finished the track... now it's random time
      }
      for (j = 0; j < 4; j ++)
      {
       mtrack_position [j] = 0;
       mtrack_count [j] = 0;
       mtrack_music [j] = overmusic [overposition] [j] [0];
       mtrack_volume [j] = overmusic [overposition] [j] [4];
       mtrack_tone_offset [j] = overmusic [overposition] [j] [2];
      }
      return;
     }
   }


  if (mtrack_count [i] <= 0)
  {

/*   if (music [mtrack_music [i]] [mtrack_position [i]] [0] != BEAT_WAIT
      && music [mtrack_music [i]] [mtrack_position [i]] [0] != BEAT_EMPTY)
//   if (music [mtrack_music [i]] [mtrack_position [i]] [0] == BEAT_START
//      || music [mtrack_music [i]] [mtrack_position [i]] [0] == BEAT_BOOM)
    play_sample(beat [music [mtrack_music [i]] [mtrack_position [i]] [0]], (int) ((100 + mtrack_volume [i]) * options.ambience_volume) / 100, music [mtrack_music [i]] [mtrack_position [i]] [3], tone [music [mtrack_music [i]] [mtrack_position [i]] [1] + mtrack_tone_offset [i]], 0);
*/
  if (music [mtrack_music [i]] [mtrack_position [i]] [0] < NO_BEATS)
  {
    if (mtrack_glitchy [i] < grand(10) + 1)
    {
     if (mtrack_force_beat [i] == -1)
      play_sample(beat [music [mtrack_music [i]] [mtrack_position [i]] [0]], (int) ((100 + mtrack_volume [i]) * options.ambience_volume) / 100, music [mtrack_music [i]] [mtrack_position [i]] [3], tone [music [mtrack_music [i]] [mtrack_position [i]] [1] + mtrack_tone_offset [i]], 0);
       else
//        play_sample(beat [BEAT_TOM], (int) ((100 + mtrack_volume [i]) * options.ambience_volume) / 100, music [mtrack_music [i]] [mtrack_position [i]] [3], tone [music [mtrack_music [i]] [mtrack_position [i]] [1] + mtrack_tone_offset [i]], 0);
        play_sample(beat [mtrack_force_beat [i]], (int) ((100 + mtrack_volume [i]) * options.ambience_volume) / 100, music [mtrack_music [i]] [mtrack_position [i]] [3], tone [music [mtrack_music [i]] [mtrack_position [i]] [1] + mtrack_tone_offset [i]], 0);
    }
  }

//   play_sample(beat [BEAT_BOOM], (int) (190 * options.ambience_volume) / 100, music [0] [mtrack_position] [3], tone [music [0] [mtrack_position] [1] + 13], 0);
   mtrack_count [i] = music [mtrack_music [i]] [mtrack_position [i]] [2];
  // fix so ambi_volume
   mtrack_position [i] ++;
  }

 }

}

/*
void run_mtracks()
{

 //if (arena.counter % 4 == 0)
mtrack_count --;

 if (mtrack_count == 0)
 {
  if (music [0] [mtrack_position] [0] == BEAT_EMPTY)
   mtrack_position = 0;
  play_sample(beat [music [0] [mtrack_position] [0]], (int) (50 * options.ambience_volume) / 100, music [0] [mtrack_position] [3], tone [music [0] [mtrack_position] [1]], 0);
//play_sample(beat [BEAT_BOOM], (int) (190 * options.ambience_volume) / 100, music [0] [mtrack_position] [3], tone [music [0] [mtrack_position] [1] + 13], 0);
  mtrack_count = music [0] [mtrack_position] [2];
  // fix so ambi_volume
  mtrack_position ++;
 }

boomtrack_count --;

 if (boomtrack_count == 0)
 {
  if (music [1] [boomtrack_position] [0] == BEAT_EMPTY)
   boomtrack_position = 0;
  play_sample(beat [music [1] [boomtrack_position] [0]], (int) (150 * options.ambience_volume) / 100, music [1] [boomtrack_position] [3], tone [music [1] [boomtrack_position] [1] + 18], 0);
  boomtrack_count = music [1] [boomtrack_position] [2];
  // fix so ambi_volume
  boomtrack_position ++;
 }


}*/



void make_random_mtrack(void)
{

 int i = 0;

 random_track_length --;

 if (random_track_length > 0)
 {
  for (i = 0; i < 4; i ++)
  {
   mtrack_position [i] = 0;
   mtrack_count [i] = 0;
//   mtrack_force_beat [i] = -1;
//   mtrack_glitchy [i] = 0;
  }
  return;
 }

 random_track_length = 1 + grand(2) + grand(2) + grand(2) + grand(2) + grand(2);

 for (i = 0; i < 4; i ++)
 {
  mtrack_music [i] = MUSIC_EMPTY;
  mtrack_position [i] = 0;
  mtrack_count [i] = 0;
  mtrack_glitchy [i] = 0;
  mtrack_force_beat [i] = -1;
 }


// int level = 0;

 i = 0;

 if (grand(5) == 0)
 {
   switch(grand(9))
   {
     case 0:
      random_tone = 3; break;
     case 1:
      random_tone = 7; break;
     case 2:
      random_tone = 4; break;
     case 3:
      random_tone = -3; break;
     default:
      random_tone = 0; break;
   }
 }


 if (grand(4) != 0)
 {
  mtrack_music [i] = MUSIC_SNARE2;
  mtrack_volume [i] = 100;
  if (grand(8))
   mtrack_volume [i] = 50 + grand(100);
  mtrack_tone_offset [i] = 20;
  if (!grand(8))
   mtrack_tone_offset [i] = 13 + grand(3) * 7;
  i ++;
 }

 if (grand(4) != 0)
 {
  mtrack_music [i] = MUSIC_BOOM;
  mtrack_volume [i] = 100;
  if (grand(8))
   mtrack_volume [i] = 50 + grand(100);
  mtrack_tone_offset [i] = 13;
  if (grand(4))
  {
      switch(grand(4))
      {
       case 0: mtrack_tone_offset [i] = 13 + 3; break;
       case 1: mtrack_tone_offset [i] = 13 + 4; break;
       case 2: mtrack_tone_offset [i] = 13 + 6; break;
       case 3: mtrack_tone_offset [i] = 13 + 7; break;
      }
  }
  if (grand(4) != 0)
   mtrack_tone_offset [i] += random_tone;

  if (grand(6) == 0)
   mtrack_force_beat [i] = BEAT_START;
  if (grand(6) == 0)
  {
   mtrack_force_beat [i] = BEAT_TOM;
   mtrack_volume [i] = -10 - grand(20);
  }

  if (grand (6) == 0)
   mtrack_glitchy [i] = 0 - grand(20);//grand(6) + 3;

  i ++;
// i++ must be LAST!!!
 }

 if (grand(4) != 0 || i == 0)
 {
  switch(grand(8))
  {
    default:
    case 0: mtrack_music [i] = MUSIC_BASIC; break;
    case 1: mtrack_music [i] = MUSIC_START2; break;
    case 2: mtrack_music [i] = MUSIC_START3; break;
    case 3: mtrack_music [i] = MUSIC_START4; break;
  }
  mtrack_volume [i] = -40;
  if (grand(8))
   mtrack_volume [i] = -60 + grand(20);
  mtrack_tone_offset [i] = 13;
//  if (grand(8))
//   mtrack_tone_offset [i] = 13 + grand(4) * 7;
  if (grand(5) != 0)
   mtrack_tone_offset [i] += random_tone;

  if (grand(5) == 0)
  {
   mtrack_force_beat [i] = BEAT_TOM;
   mtrack_volume [i] = -10 - grand(20);//20 + grand(5);
  }

  if (grand (4) == 0)
   mtrack_glitchy [i] = grand(5) + 2;
  i ++;

// i++ must be LAST!!!
 }


/*
{
MUSIC_BASIC,
MUSIC_START2,
MUSIC_BOOM,
MUSIC_SNARE,
MUSIC_SNARE2,
MUSIC_BOOM2,
MUSIC_START3,
MUSIC_START4,
MUSIC_WAIT,
MUSIC_EMPTY,
MUSIC_END
};
*/


}


void run_loops(void)
{

 if (sound_active == 0 || options.sound_volume == 0) return;


 if (arena.old_beam == 0)
 {
  if (arena.beam == 1)
  {
   play_sample(new_sounds [NWAV_BEAM2], (int) (150 * options.sound_volume) / 100, 127, 550, 1);
  }
 }
  else
  {
   if (arena.beam == 0)
   {
    stop_sample(new_sounds [NWAV_BEAM2]);
    play_sample(new_sounds [NWAV_BEAM3], (int) (150 * options.sound_volume) / 100, 127, 550, 0);
   }
  }

 if (player.blue_was_firing == 0)
 {
  if (player.blue_fire > 0)
  {
   play_sample(new_sounds [NWAV_PBEAM1], (int) (200 * options.sound_volume) / 100, 127, 1500, 1);
  }
 }
  else
  {
   if (player.blue_fire == 0)
   {
    stop_sample(new_sounds [NWAV_PBEAM1]);
    player.blue_was_firing = 0;
//    exit(1);
   }
  }


}


void load_new_sample_in(int samp, const char *sfile)
{

 char sfile_name [50];

 strcpy(sfile_name, ".//wavs//");
 strcat(sfile_name, sfile);
 strcat(sfile_name, ".wav");

 new_sounds [samp] = load_sample(sfile_name);

 if (new_sounds [samp] == NULL)
 {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      allegro_message("Error: Unable to load sound file: %s", sfile_name);
      exit(1);
 }
}

void load_new_ambi_in(int samp, const char *sfile)
{

 char sfile_name [50];

 strcpy(sfile_name, ".//wavs//ambi//");
 strcat(sfile_name, sfile);
 strcat(sfile_name, ".wav");

 beat [samp] = load_sample(sfile_name);

 if (beat [samp] == NULL)
 {
      set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
      allegro_message("Error: Unable to load ambience file: %s", sfile_name);
      exit(1);
 }
}

void play_effect(int sample)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

 play_sample(new_sounds [sample], (int) (250 * options.sound_volume) / 100, 127, 1000, 0);

}

void play_effectf(int sample, int freq)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

 play_sample(new_sounds [sample], (int) (250 * options.sound_volume) / 100, 127, freq, 0);

}





void play_effectw(int w, int sample)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

 int pan = 63;
 if (w == 1)
  pan = 191;

 switch(options.sound_mode)
 {
  case SOUNDMODE_MONO:
   pan = 127;   break;
  case SOUNDMODE_REVERSED:
   pan = 255 - pan;   break;
 }

 play_sample(new_sounds [sample], (int) (250 * options.sound_volume) / 100, pan, 1000, 0);

}

void play_effectwf(int w, int sample, int f)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

 int pan = 63;
 if (w == 1)
  pan = 191;

 switch(options.sound_mode)
 {
  case SOUNDMODE_MONO:
   pan = 127;   break;
  case SOUNDMODE_REVERSED:
   pan = 255 - pan;   break;
 }


 play_sample(new_sounds [sample], (int) (250 * options.sound_volume) / 100, pan, f, 0);

}

void play_effectwfx(int w, int sample, int f, int x)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

/* int pan = 63;
 if (w == 1)
  pan = 191;*/

 int pan = x / 3200;
 if (w == 1)
  pan += 127;

 switch(options.sound_mode)
 {
  case SOUNDMODE_MONO:
   pan = 127;   break;
  case SOUNDMODE_REVERSED:
   pan = 255 - pan;   break;
 }

 play_sample(new_sounds [sample], (int) (250 * options.sound_volume) / 100, pan, f, 0);

}


void play_effectwfvx(int w, int sample, int f, int v, int x)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

/* int pan = 63;
 if (w == 1)
  pan = 191;*/

 int pan = x / 3200;
 if (w == 1)
  pan += 127;

 switch(options.sound_mode)
 {
  case SOUNDMODE_MONO:
   pan = 127;   break;
  case SOUNDMODE_REVERSED:
   pan = 255 - pan;   break;
 }

 play_sample(new_sounds [sample], (int) (v * options.sound_volume) / 100, pan, f, 0);

}












void play_wav(int sample)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;

 play_sample(new_sounds [sample], (int) (250 * options.sound_volume) / 100, 127, 1000, 0);

}

void play_wav2(int sample, int frq, int vol, int pan)
{
#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;
/*
 stop_sample(soundf[WAV_POP].dat);
 stop_sample(soundf[WAV_RICOCHET].dat);
 if (sample == WAV_S_PULSE)
  stop_sample(soundf[WAV_S_PULSE].dat);*/
// stop_sample(sounds [sample]);
 play_sample(new_sounds [sample], (vol * options.sound_volume) / 100, pan, frq, 0);


}

void play_wavf(int sample, int frq)
{

#ifdef SOUND_OFF
 return;
#endif

 if (sound_active == 0 || options.sound_volume == 0) return;
 play_sample(new_sounds [sample], (int) (255 * options.sound_volume) / 100, 127, frq, 0);


}

