|
1 /* |
|
2 * commands.c |
|
3 * Hedgewars |
|
4 * |
|
5 * Created by Vittorio on 13/06/10. |
|
6 * Copyright 2010 __MyCompanyName__. All rights reserved. |
|
7 * |
|
8 */ |
|
9 |
|
10 #include "commands.h" |
|
11 #include "wrappers.h" |
|
12 |
|
13 ALfloat old_gain; |
|
14 extern ALuint *Sources; |
|
15 extern ALuint cache_size, cache_index, sources_number; |
|
16 extern ALboolean instances_number; |
|
17 extern al_sound_t *the_sounds; |
|
18 |
|
19 void openal_pausesound (uint32_t index) { |
|
20 if (openal_ready() == AL_TRUE && index < cache_size) |
|
21 alSourcePause(Sources[the_sounds[index].source_index]); |
|
22 } |
|
23 |
|
24 |
|
25 void openal_stopsound (uint32_t index) { |
|
26 if (openal_ready() == AL_TRUE && index < cache_size) |
|
27 alSourceStop(Sources[the_sounds[index].source_index]); |
|
28 } |
|
29 |
|
30 |
|
31 void openal_playsound (unsigned int index) { |
|
32 ALboolean needsSource = AL_TRUE; |
|
33 ALfloat SourcePosition[] = { 0.0, 0.0, 0.0 }; |
|
34 ALfloat SourceVelocity[] = { 0.0, 0.0, 0.0 }; |
|
35 ALint state; |
|
36 int i, j; |
|
37 |
|
38 if (openal_ready() == AL_TRUE && index < cache_size) { |
|
39 // check if sound has already a source |
|
40 if (the_sounds[index].source_index != -1) { |
|
41 // it has a source, check it's not playing |
|
42 alGetSourcei(Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state); |
|
43 if (state != AL_PLAYING && state != AL_PAUSED) { |
|
44 // it is not being played, so we can use it safely |
|
45 needsSource = AL_FALSE; |
|
46 } |
|
47 // else it is being played, so we have to allocate a new source for this buffer |
|
48 } |
|
49 |
|
50 if (needsSource) { |
|
51 #ifdef DEBUG |
|
52 fprintf(stderr,"(Bridge Debug) - looking for a source for sound %d\n", index); |
|
53 #endif |
|
54 for (i = 0; i < sources_number; i++) { |
|
55 // let's iterate on Sources until we find a source that is not playing |
|
56 alGetSourcei(Sources[i], AL_SOURCE_STATE, &state); |
|
57 if (state != AL_PLAYING && state != AL_PAUSED) { |
|
58 // let's iterate on the_sounds until we find the sound using that source |
|
59 for (j = 0; j < cache_size; j++) { |
|
60 if (the_sounds[j].source_index == i) { |
|
61 the_sounds[j].source_index = -1; |
|
62 break; |
|
63 } |
|
64 } |
|
65 // here we know that no-one is using that source so we can use it |
|
66 break; |
|
67 } |
|
68 } |
|
69 |
|
70 if (i == sources_number) { |
|
71 // this means all sources are busy |
|
72 } |
|
73 |
|
74 // set source properties that it will use when it's in playback |
|
75 alSourcei (Sources[i], AL_BUFFER, the_sounds[index].buffer); |
|
76 alSourcef (Sources[i], AL_PITCH, 1.0f); |
|
77 alSourcef (Sources[i], AL_GAIN, 1.0f); |
|
78 alSourcefv(Sources[i], AL_POSITION, SourcePosition); |
|
79 alSourcefv(Sources[i], AL_VELOCITY, SourceVelocity); |
|
80 alSourcei (Sources[i], AL_LOOPING, 0); |
|
81 |
|
82 if (AL_NO_ERROR != alGetError()) { |
|
83 fprintf(stderr,"(Bridge ERROR) - failed to set Source properties\n"); |
|
84 return; |
|
85 } |
|
86 the_sounds[index].source_index = i; |
|
87 } |
|
88 |
|
89 alSourcePlay(Sources[the_sounds[index].source_index]); |
|
90 |
|
91 if (AL_NO_ERROR != alGetError()) { |
|
92 fprintf(stderr,"(Bridge Warning) - failed to play sound %d\n", index); |
|
93 return; |
|
94 } |
|
95 |
|
96 the_sounds[index].stats++; |
|
97 } |
|
98 } |
|
99 |
|
100 void openal_toggleloop (uint32_t index) { |
|
101 ALint loop; |
|
102 |
|
103 if (openal_ready() == AL_TRUE && index < cache_size) { |
|
104 alGetSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, &loop); |
|
105 alSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, !((uint8_t) loop) & 0x00000001); |
|
106 } |
|
107 } |
|
108 |
|
109 |
|
110 void openal_setvolume (uint32_t index, float gain) { |
|
111 if (openal_ready() == AL_TRUE && index < cache_size) |
|
112 alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, gain); |
|
113 } |
|
114 |
|
115 |
|
116 void openal_setglobalvolume (float gain) { |
|
117 if (openal_ready() == AL_TRUE) |
|
118 alListenerf (AL_GAIN, gain); |
|
119 } |
|
120 |
|
121 void openal_togglemute () { |
|
122 ALfloat gain; |
|
123 |
|
124 if (openal_ready() == AL_TRUE) { |
|
125 alGetListenerf (AL_GAIN, &gain); |
|
126 if (gain > 0) { |
|
127 old_gain = gain; |
|
128 gain = 0; |
|
129 } else |
|
130 gain = old_gain; |
|
131 |
|
132 alListenerf (AL_GAIN, gain); |
|
133 } |
|
134 } |
|
135 |
|
136 // Fade in or out by calling a helper thread |
|
137 void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) { |
|
138 #ifndef _WIN32 |
|
139 pthread_t thread; |
|
140 #else |
|
141 HANDLE Thread; |
|
142 #endif |
|
143 fade_t *fade; |
|
144 |
|
145 if (openal_ready() == AL_TRUE && index < cache_size) { |
|
146 fade = (fade_t*) Malloc(sizeof(fade_t)); |
|
147 fade->index = index; |
|
148 fade->quantity = quantity; |
|
149 fade->type = direction; |
|
150 |
|
151 #ifndef _WIN32 |
|
152 pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade); |
|
153 pthread_detach(thread); |
|
154 #else |
|
155 Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade); |
|
156 #endif |
|
157 } |
|
158 } |
|
159 |
|
160 void openal_setposition (uint32_t index, float x, float y, float z) { |
|
161 if (openal_ready() == AL_TRUE && index < cache_size) |
|
162 alSource3f(Sources[the_sounds[index].source_index], AL_POSITION, x, y, z);; |
|
163 } |
|
164 |
|
165 void helper_fade(void *tmp) { |
|
166 ALfloat gain; |
|
167 ALfloat target_gain; |
|
168 fade_t *fade; |
|
169 uint32_t index; |
|
170 uint16_t quantity; |
|
171 al_fade_t type; |
|
172 |
|
173 fade = tmp; |
|
174 index = fade->index; |
|
175 quantity = fade->quantity; |
|
176 type = fade->type; |
|
177 free (fade); |
|
178 |
|
179 if (type == AL_FADE_IN) { |
|
180 #ifdef DEBUG |
|
181 fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity); |
|
182 #endif |
|
183 |
|
184 // save the volume desired after the fade |
|
185 alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain); |
|
186 if (target_gain > 1.0f || target_gain <= 0.0f) |
|
187 target_gain = 1.0f; |
|
188 |
|
189 for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) { |
|
190 #ifdef TRACE |
|
191 fprintf(stderr,"(Bridge Debug) - Fade-in set gain to %f\n", gain); |
|
192 #endif |
|
193 alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain); |
|
194 usleep(10000); |
|
195 } |
|
196 } else { |
|
197 alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain); |
|
198 |
|
199 for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) { |
|
200 #ifdef TRACE |
|
201 fprintf(stderr,"(Bridge Debug) - Fade-out set gain to %f\n", gain); |
|
202 #endif |
|
203 alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain); |
|
204 usleep(10000); |
|
205 } |
|
206 |
|
207 if (AL_NO_ERROR != alGetError()) |
|
208 fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect\n"); |
|
209 |
|
210 // stop that sound and reset its volume |
|
211 alSourceStop (Sources[the_sounds[index].source_index]); |
|
212 alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, target_gain); |
|
213 } |
|
214 |
|
215 if (AL_NO_ERROR != alGetError()) |
|
216 fprintf(stderr,"(Bridge Warning) - Failed to set fade effect\n"); |
|
217 |
|
218 #ifndef _WIN32 |
|
219 pthread_exit(NULL); |
|
220 #else |
|
221 _endthread(); |
|
222 #endif |
|
223 } |
|
224 |