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