1 /* ************************************************************************* *
2     OldSkoolGravityGame (OSGG) Lunar Lander-like game for linux.
3     Copyright (C) 2008 Jimmy Christensen ( dusted at dusted dot dk )
4 
5     This program is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  * ************************************************************************* */
18 
19 #include "sound.hpp"
20 
init()21 bool soundClass::init() {
22   #ifndef NOSOUND
23   m=0;
24   int audio_rate = 44100;
25   Uint16 audio_format = AUDIO_S16; /* 16-bit stereo */
26   int audio_channels = 2;
27   int audio_buffers = 1024;
28   if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)) {
29       cout << "Error: Could not open audio device."<<endl<<"Sound have been disabled."<<endl;
30       soundOn=0;
31       return(0);
32   }
33   Mix_AllocateChannels(MIX_CHANNELS);
34 
35   loadsounds();
36   #endif
37   return(1);
38 }
39 
40 #ifndef NOSOUND
loadSample(const char * SampleName,int sampleNum)41 void soundClass::loadSample(const char *SampleName, int sampleNum)
42 {
43   string F=DATADIR;
44   F += SampleName;
45 
46   sample[sampleNum] = Mix_LoadWAV(F.data());
47   if(!sample[sampleNum])
48   {
49     cout << "SoundManager '"<< F <<"' : " << Mix_GetError() << endl;
50   }
51 }
52 #endif
53 
54 
55 /* This function puts a sample in queue for playing */
add(int i)56 void soundClass::add(int i)
57 {
58   #ifndef NOSOUND
59   if(!soundOn) return;
60   struct sampleQueuedItem qt;
61   qt.s=i;
62   q.push_back( qt );
63 
64   #endif
65 }
66 
loadsounds()67 void soundClass::loadsounds()
68 {
69 
70   #ifndef NOSOUND
71   loadSample("nozzloop.ogg", sfxNozzle);
72   loadSample("boom.ogg", sfxBoom);
73   loadSample("laser.ogg", sfxLaser);
74   #endif
75 }
76 
77 /* This function is called only when drawing a frame, and plays the queue of samples,
78    It will average the x/stereo position of a sample if it is queued more than once */
play()79 void soundClass::play()
80 {
81   #ifndef NOSOUND
82   if(!soundOn) return;
83 
84   //Playlist (lol, imagination for the win..)
85   vector<struct sampleQueuedItem> pl;
86   vector<struct sampleQueuedItem>::iterator plIt;
87   bool same=0;
88   int freeChannel = -1; //The channel we will use for this sample
89 
90   //Loop through queue and find samples thare are the same,and put in a new vector
91   for(vector<struct sampleQueuedItem>::iterator it = q.begin(); it != q.end(); ++it)
92   {
93     //Loop thrugh the playlist to see find out if this allready exist
94     same=0;
95     for(plIt=pl.begin(); plIt != pl.end(); ++plIt)
96     {
97       if(plIt->s == it->s)
98       {
99         same=1;
100         plIt->num++;
101       }
102     }
103 
104     //this sample is not yet in the playlist
105     if(!same)
106     {
107        pl.push_back( *it );
108        plIt = pl.end();
109        --plIt;
110        plIt->num=1;
111     }
112   }
113   q.clear();
114 
115   //Play the actual samples :)
116   nozzleOn=0;
117   for(plIt = pl.begin(); plIt != pl.end(); ++plIt)
118   {
119     //Find a free channel:
120     for(int i=0; i < MIX_CHANNELS; i++)
121     {
122       if(!Mix_Playing(i))
123       {
124         freeChannel=i;
125         break;
126       }
127     }
128 
129     if(plIt->s == sfxNozzle)
130     {
131       nozzleOn = 1;
132       //Only play if not allready playing
133       if(nozzleCh == -1)
134       {
135         nozzleCh = Mix_PlayChannel(freeChannel, sample[plIt->s], -1);
136       }
137     } else {
138       if(Mix_PlayChannel(freeChannel, sample[plIt->s], 0) == -1)
139       {
140         printf("Sample %i: %s\n",plIt->s, Mix_GetError());
141       }
142     }
143   }
144 
145   //Check to see if the nozzle is on
146   if(!nozzleOn)
147   {
148     //Kill the sound
149     if(nozzleCh > -1)
150       Mix_FadeOutChannel(nozzleCh,32);
151     nozzleCh = -1;
152   }
153   #endif
154 }
155 
~soundClass()156 soundClass::~soundClass()
157 {
158   #ifndef NOSOUND
159   for(int i=0; i < SNDSAMPLES; i++)
160   {
161     Mix_FreeChunk(sample[i]);
162   }
163   Mix_CloseAudio();
164   #endif
165 }
166