1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | //#define INITGUID
|
---|
10 |
|
---|
11 | #include "error/error.hh"
|
---|
12 | #include "error/alert.hh"
|
---|
13 | #include "sound/dsound/d3dsound.hh"
|
---|
14 | #include "loaders/wav_load.hh"
|
---|
15 | #include "string/string.hh"
|
---|
16 | #include "file/file.hh"
|
---|
17 | #include "video/win32/win32.hh"
|
---|
18 |
|
---|
19 | direct_3dsound_class direct_3dsound;
|
---|
20 | static sw16 volume_table[I4_SOUND_VOLUME_LEVELS] =
|
---|
21 | {
|
---|
22 | // Volume ramp
|
---|
23 | //{{{ Note:
|
---|
24 | // Generated with:
|
---|
25 | //
|
---|
26 | // perl -e 'printf " %6d, ", -10000; for ($i=1; $i<64; $i++)
|
---|
27 | // { printf( "%6d, ", 1000*log($i/63)); if ($i%10 == 9) { print "\n "; }}; print "\n"'
|
---|
28 | //}}}
|
---|
29 |
|
---|
30 | -10000, -4143, -3449, -3044, -2756, -2533, -2351, -2197, -2063, -1945,
|
---|
31 | -1840, -1745, -1658, -1578, -1504, -1435, -1370, -1309, -1252, -1198,
|
---|
32 | -1147, -1098, -1052, -1007, -965, -924, -885, -847, -810, -775,
|
---|
33 | -741, -709, -677, -646, -616, -587, -559, -532, -505, -479,
|
---|
34 | -454, -429, -405, -381, -358, -336, -314, -292, -271, -251,
|
---|
35 | -231, -211, -191, -172, -154, -135, -117, -100, -82, -65,
|
---|
36 | -48, -32, -16, 0
|
---|
37 | };
|
---|
38 |
|
---|
39 | int check_result(HRESULT err)
|
---|
40 | //{{{
|
---|
41 | {
|
---|
42 | switch (err)
|
---|
43 | {
|
---|
44 | case DS_OK:
|
---|
45 | return 1;
|
---|
46 | break;
|
---|
47 |
|
---|
48 | case DSERR_ALLOCATED:
|
---|
49 | i4_warning("i4_direct_sound - resources already used by another.");
|
---|
50 | break;
|
---|
51 |
|
---|
52 | case DSERR_ALREADYINITIALIZED:
|
---|
53 | i4_warning("i4_direct_sound - object already initialized.");
|
---|
54 | break;
|
---|
55 |
|
---|
56 | case DSERR_BADFORMAT:
|
---|
57 | i4_warning("i4_direct_sound - format not supported.");
|
---|
58 | break;
|
---|
59 |
|
---|
60 | case DSERR_BUFFERLOST:
|
---|
61 | i4_warning("i4_direct_sound - buffer memory lost.");
|
---|
62 | break;
|
---|
63 |
|
---|
64 | case DSERR_CONTROLUNAVAIL:
|
---|
65 | i4_warning("i4_direct_sound - control is unavailable.");
|
---|
66 | break;
|
---|
67 |
|
---|
68 | case DSERR_GENERIC:
|
---|
69 | i4_warning("i4_direct_sound - error.");
|
---|
70 | break;
|
---|
71 |
|
---|
72 | case DSERR_INVALIDCALL:
|
---|
73 | i4_warning("i4_direct_sound - function is invalid.");
|
---|
74 | break;
|
---|
75 |
|
---|
76 | case DSERR_INVALIDPARAM:
|
---|
77 | i4_warning("i4_direct_sound - invalid parameter.");
|
---|
78 | break;
|
---|
79 |
|
---|
80 | case DSERR_NOAGGREGATION:
|
---|
81 | i4_warning("i4_direct_sound - object does not support aggregation.");
|
---|
82 | break;
|
---|
83 |
|
---|
84 | case DSERR_NODRIVER:
|
---|
85 | i4_warning("i4_direct_sound - no sound driver available.");
|
---|
86 | break;
|
---|
87 |
|
---|
88 | case DSERR_OUTOFMEMORY:
|
---|
89 | i4_warning("i4_direct_sound - out of memory.");
|
---|
90 | break;
|
---|
91 |
|
---|
92 | case DSERR_PRIOLEVELNEEDED:
|
---|
93 | i4_warning("i4_direct_sound - insufficient priority level to perform function.");
|
---|
94 | break;
|
---|
95 |
|
---|
96 | case DSERR_UNINITIALIZED:
|
---|
97 | i4_warning("i4_direct_sound - uninitializd sound system.");
|
---|
98 | break;
|
---|
99 |
|
---|
100 | case DSERR_UNSUPPORTED:
|
---|
101 | i4_warning("i4_direct_sound - function currently unsupported.");
|
---|
102 | break;
|
---|
103 | }
|
---|
104 | return 0;
|
---|
105 | }
|
---|
106 | //}}}
|
---|
107 |
|
---|
108 |
|
---|
109 | void d3dsound_buffer_class::play()
|
---|
110 | //{{{
|
---|
111 | {
|
---|
112 | if (!pDSB)
|
---|
113 | return;
|
---|
114 |
|
---|
115 | // pDSB->SetCurrentPosition(0);
|
---|
116 | pDSB->Play(0,0,flags);
|
---|
117 | }
|
---|
118 | //}}}
|
---|
119 |
|
---|
120 |
|
---|
121 | void d3dsound_buffer_class::update()
|
---|
122 | //{{{
|
---|
123 | {
|
---|
124 | if (!pDSB)
|
---|
125 | return;
|
---|
126 |
|
---|
127 | pDSB->SetFrequency(frequency);
|
---|
128 | pDSB->SetVolume(volume_table[volume]);
|
---|
129 |
|
---|
130 | ds_param.vPosition.x = position.x*0.01;
|
---|
131 | ds_param.vPosition.y = position.y*0.01;
|
---|
132 | ds_param.vPosition.z = position.z*0.01;
|
---|
133 | ds_param.vVelocity.x = velocity.x*0.5;
|
---|
134 | ds_param.vVelocity.y = velocity.y*0.5;
|
---|
135 | ds_param.vVelocity.z = velocity.z*0.5;
|
---|
136 |
|
---|
137 | pDS3DB->SetAllParameters(&ds_param, DS3D_IMMEDIATE);
|
---|
138 | }
|
---|
139 | //}}}
|
---|
140 |
|
---|
141 |
|
---|
142 | void d3dsound_buffer_class::set_completer(completion_function_type _completer, void *_context)
|
---|
143 | //{{{
|
---|
144 | {
|
---|
145 | completer = _completer;
|
---|
146 | context = _context;
|
---|
147 | }
|
---|
148 | //}}}
|
---|
149 |
|
---|
150 |
|
---|
151 | void direct_3dsound_class::load(w32 max_sounds)
|
---|
152 | //{{{
|
---|
153 | {
|
---|
154 | sound = new d3dsound_buffer_class[max_sounds];
|
---|
155 |
|
---|
156 | i4_sound_info info;
|
---|
157 | i4_const_str *sounds=i4_string_man.get_array("sounds");
|
---|
158 |
|
---|
159 | for (w32 count=0; !sounds[count].null(); count++)
|
---|
160 | {
|
---|
161 | i4_file_class *fp=i4_file_man.open(sounds[count]);
|
---|
162 | if (!fp)
|
---|
163 | i4_alert(i4gets("file_missing"),200,&sounds[count]);
|
---|
164 | else
|
---|
165 | {
|
---|
166 | if (i4_load_wav(fp,info))
|
---|
167 | {
|
---|
168 | DSBUFFERDESC dsBD = {0};
|
---|
169 | PCMWAVEFORMAT pcmwf;
|
---|
170 | d3dsound_buffer_class *snd = &sound[count];
|
---|
171 |
|
---|
172 | ZeroMemory(&pcmwf, sizeof(PCMWAVEFORMAT));
|
---|
173 | pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
|
---|
174 | pcmwf.wf.nChannels = info.channels;
|
---|
175 | pcmwf.wf.nSamplesPerSec = info.sample_rate;
|
---|
176 | pcmwf.wf.nBlockAlign = info.sample_size*info.channels;
|
---|
177 | pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
|
---|
178 | pcmwf.wBitsPerSample = info.sample_size*8;
|
---|
179 |
|
---|
180 | dsBD.dwSize = sizeof(dsBD);
|
---|
181 | dsBD.dwFlags = DSBCAPS_CTRL3D | DSBCAPS_CTRLFREQUENCY | DSBCAPS_CTRLVOLUME;
|
---|
182 | dsBD.dwBufferBytes = info.size;
|
---|
183 | dsBD.lpwfxFormat = (LPWAVEFORMATEX)&pcmwf;
|
---|
184 |
|
---|
185 | if (!check_result(lpDirectSound->CreateSoundBuffer(&dsBD, &snd->pDSB, 0)))
|
---|
186 | {
|
---|
187 | i4_warning("couldn't create sound buffer");
|
---|
188 | snd->pDSB = 0;
|
---|
189 | return;
|
---|
190 | }
|
---|
191 |
|
---|
192 | if (!check_result(snd->pDSB->QueryInterface(IID_IDirectSound3DBuffer,
|
---|
193 | (void**)&snd->pDS3DB)))
|
---|
194 | {
|
---|
195 | i4_warning("couldn't create 3D sound buffer");
|
---|
196 | snd->pDSB = 0;
|
---|
197 | snd->pDS3DB = 0;
|
---|
198 | return;
|
---|
199 | }
|
---|
200 |
|
---|
201 | snd->ds_param.dwSize = sizeof(snd->ds_param);
|
---|
202 | snd->ds_param.vPosition.x = 0;
|
---|
203 | snd->ds_param.vPosition.y = 0;
|
---|
204 | snd->ds_param.vPosition.z = 0;
|
---|
205 | snd->ds_param.vVelocity.x = 0;
|
---|
206 | snd->ds_param.vVelocity.y = 0;
|
---|
207 | snd->ds_param.vVelocity.z = 0;
|
---|
208 | snd->ds_param.dwInsideConeAngle = 360;
|
---|
209 | snd->ds_param.dwOutsideConeAngle = 360;
|
---|
210 | snd->ds_param.vConeOrientation.x;
|
---|
211 | snd->ds_param.vConeOrientation.y;
|
---|
212 | snd->ds_param.vConeOrientation.z;
|
---|
213 | snd->ds_param.lConeOutsideVolume = 0;
|
---|
214 | snd->ds_param.flMinDistance = 1;
|
---|
215 | snd->ds_param.flMaxDistance = 100;
|
---|
216 | snd->ds_param.dwMode = DS3DMODE_NORMAL;
|
---|
217 |
|
---|
218 | check_result(snd->pDS3DB->SetAllParameters(&snd->ds_param, DS3D_IMMEDIATE));
|
---|
219 |
|
---|
220 | LPVOID m1,m2;
|
---|
221 | DWORD s1,s2;
|
---|
222 |
|
---|
223 | snd->data = (w8*)info.data;
|
---|
224 |
|
---|
225 | if (!check_result(snd->pDSB->Lock(0, info.size, &m1, &s1, &m2, &s2, 0)))
|
---|
226 | {
|
---|
227 | i4_warning("i4_sound_manager_class::play - couldn't get write access to sound buffer");
|
---|
228 | snd->pDSB->Release();
|
---|
229 | snd->pDSB = 0;
|
---|
230 | return;
|
---|
231 | }
|
---|
232 |
|
---|
233 | CopyMemory(m1, snd->data, s1);
|
---|
234 |
|
---|
235 | if (s2 != 0)
|
---|
236 | CopyMemory(m2, snd->data+s1, s2);
|
---|
237 |
|
---|
238 | if (!check_result(snd->pDSB->Unlock(m1,s1,m2,s2)))
|
---|
239 | {
|
---|
240 | i4_warning("i4_3d_sound_manager_class::load - couldn't unlock sound buffer");
|
---|
241 | snd->pDSB->Release();
|
---|
242 | snd->pDSB = 0;
|
---|
243 | return;
|
---|
244 | }
|
---|
245 | }
|
---|
246 | delete fp;
|
---|
247 | }
|
---|
248 | }
|
---|
249 |
|
---|
250 | i4_free(sounds);
|
---|
251 | }
|
---|
252 | //}}}
|
---|
253 |
|
---|
254 |
|
---|
255 | void direct_3dsound_class::load_sounds(w32 max_sounds)
|
---|
256 | //{{{
|
---|
257 | {
|
---|
258 | i4_3d_sound_man = (i4_3d_sound_manager_class*)&i4_null_3d_sound;
|
---|
259 |
|
---|
260 | DSBUFFERDESC dsBD;
|
---|
261 |
|
---|
262 | if (DirectSoundCreate(0, &lpDirectSound, 0) != DS_OK)
|
---|
263 | {
|
---|
264 | i4_warning("i4_sound_manager_class::load_sounds - DirectSound not initialized");
|
---|
265 | return;
|
---|
266 | }
|
---|
267 |
|
---|
268 | if (lpDirectSound->SetCooperativeLevel(win32_display_instance.window_handle,
|
---|
269 | DSSCL_EXCLUSIVE) != DS_OK)
|
---|
270 | {
|
---|
271 | i4_warning("i4_sound_manager_class::load_sounds - couldn't get exclusive sound");
|
---|
272 | return;
|
---|
273 | }
|
---|
274 |
|
---|
275 | ZeroMemory( &dsBD, sizeof(DSBUFFERDESC) );
|
---|
276 | dsBD.dwSize = sizeof(dsBD);
|
---|
277 | dsBD.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
---|
278 |
|
---|
279 | if (!check_result( lpDirectSound->CreateSoundBuffer( &dsBD, &lpPrimary, 0)))
|
---|
280 | {
|
---|
281 | i4_warning("i4_sound_manager_class::load_sounds - couldn't create primary buffer");
|
---|
282 | return;
|
---|
283 | }
|
---|
284 |
|
---|
285 | #if 0
|
---|
286 | PCMWAVEFORMAT pcmwf;
|
---|
287 | ZeroMemory(&pcmwf, sizeof(PCMWAVEFORMAT));
|
---|
288 | pcmwf.wf.wFormatTag = WAVE_FORMAT_PCM;
|
---|
289 | pcmwf.wf.nChannels = 1;
|
---|
290 | pcmwf.wf.nSamplesPerSec = 22050;
|
---|
291 | pcmwf.wf.nBlockAlign = 1;
|
---|
292 | pcmwf.wf.nAvgBytesPerSec = pcmwf.wf.nSamplesPerSec * pcmwf.wf.nBlockAlign;
|
---|
293 | pcmwf.wBitsPerSample = 8;
|
---|
294 |
|
---|
295 | if (!check_result( lpPrimary->SetFormat((LPWAVEFORMATEX)&pcmwf) ))
|
---|
296 | {
|
---|
297 | i4_warning("i4_sound_manager_class::load_sounds - couldn't format primary buffer");
|
---|
298 | return;
|
---|
299 | }
|
---|
300 | #endif
|
---|
301 |
|
---|
302 | if (!check_result( lpPrimary->Play( 0, 0, DSBPLAY_LOOPING ) ))
|
---|
303 | {
|
---|
304 | i4_warning("i4_sound_manager_class::load_sounds - couldn't start primary buffer");
|
---|
305 | return;
|
---|
306 | }
|
---|
307 |
|
---|
308 | lpPrimary->Release();
|
---|
309 |
|
---|
310 | i4_3d_sound_man = this;
|
---|
311 |
|
---|
312 | load(max_sounds);
|
---|
313 | }
|
---|
314 | //}}}
|
---|
315 |
|
---|
316 |
|
---|
317 | i4_3d_voice_class *direct_3dsound_class::alloc(i4_sound_id sound_id,
|
---|
318 | const i4_3d_sound_parameters& param)
|
---|
319 | //{{{
|
---|
320 | {
|
---|
321 | sound[sound_id].flags = 0;
|
---|
322 | if (param.looping)
|
---|
323 | sound[sound_id].flags |= DSBPLAY_LOOPING;
|
---|
324 |
|
---|
325 | sound[sound_id].set_completer(0,0);
|
---|
326 | sound[sound_id].set(param);
|
---|
327 | sound[sound_id].update();
|
---|
328 |
|
---|
329 | return &sound[sound_id];
|
---|
330 | }
|
---|
331 | //}}}
|
---|
332 |
|
---|
333 |
|
---|
334 | //{{{ Emacs Locals
|
---|
335 | // Local Variables:
|
---|
336 | // folded-file: t
|
---|
337 | // End:
|
---|
338 | //}}}
|
---|