]> icculus.org git repositories - taylor/freespace2.git/blob - src/sound/ds3d.cpp
woorps!
[taylor/freespace2.git] / src / sound / ds3d.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Sound/ds3d.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C file for interface to DirectSound3D
16  *
17  * $Log$
18  * Revision 1.2  2002/06/09 04:41:27  relnev
19  * added copyright header
20  *
21  * Revision 1.1.1.1  2002/05/03 03:28:10  root
22  * Initial import.
23  *
24  * 
25  * 12    8/05/99 4:45p Alanl
26  * the FINAL tweak to rolloffs!
27  * 
28  * 11    8/05/99 4:34p Alanl
29  * change rolloff factors again
30  * 
31  * 10    8/05/99 4:27p Danw
32  * would you believe we're still tweaking the EAX?? :)
33  * 
34  * 9     8/05/99 4:04p Danw
35  * tweak rolloffs for EAX
36  * 8     8/05/99 2:54p Danw
37  * tweak rolloffs for A3D and EAX
38  * 7     8/05/99 10:54a Alanl
39  * change EAX rolloff to 3.0
40  * 
41  * 6     8/04/99 11:51a Danw
42  * tweak rolloffs for A3D and EAX
43  * 5     8/04/99 11:42a Danw
44  * tweak rolloffs for A3D and EAX
45  * 
46  * 4     8/01/99 2:06p Alanl
47  * increase the rolloff for A3D
48  * 
49  * 3     5/23/99 8:11p Alanl
50  * Added support for EAX
51  * 
52  * 2     10/07/98 10:54a Dave
53  * Initial checkin.
54  * 
55  * 1     10/07/98 10:51a Dave
56  * 
57  * 15    5/06/98 2:16p Dan
58  * 
59  * 14    5/05/98 4:49p Lawrance
60  * Put in code to authenticate A3D, improve A3D support
61  * 
62  * 13    4/19/98 9:30p Lawrance
63  * Use Aureal_enabled flag
64  * 
65  * 12    9/09/97 3:39p Sandeep
66  * warning level 4 bugs
67  * 
68  * 11    8/01/97 10:40a Lawrance
69  * decrease rolloff for DirectSound3D sounds
70  * 
71  * 10    7/29/97 2:54p Lawrance
72  * 
73  * 9     7/28/97 11:39a Lawrance
74  * allow individual volume scaling on 3D buffers
75  * 
76  * 8     7/17/97 9:32a John
77  * made all directX header files name start with a v
78  * 
79  * 7     6/09/97 11:50p Lawrance
80  * integrating DirectSound3D
81  * 
82  * 6     6/09/97 8:53a Lawrance
83  * remove warning
84  * 
85  * 5     6/08/97 5:59p Lawrance
86  * integrate DirectSound3D into sound system
87  * 
88  * 4     6/02/97 1:45p Lawrance
89  * implementing hardware mixing
90  * 
91  * 3     5/29/97 4:02p Lawrance
92  * listener interface in place
93  * 
94  * 2     5/29/97 12:03p Lawrance
95  * creation of file to hold DirectSound3D specific code
96  *
97  * $NoKeywords: $
98  */
99
100 #include "pstypes.h"
101 #include <windows.h>
102 #include <mmreg.h>
103 #include "vdsound.h"
104
105 #include "ds3d.h"
106 #include "ds.h"
107 #include "channel.h"
108 #include "sound.h"
109 #include "object.h"
110
111 typedef enum 
112 {
113         DSPROPERTY_VMANAGER_MODE = 0,
114         DSPROPERTY_VMANAGER_PRIORITY,
115         DSPROPERTY_VMANAGER_STATE
116 } DSPROPERTY_VMANAGER;
117
118
119 typedef enum 
120 {
121         DSPROPERTY_VMANAGER_MODE_DEFAULT = 0,
122         DSPROPERTY_VMANAGER_MODE_AUTO,
123         DSPROPERTY_VMANAGER_MODE_REPORT,
124         DSPROPERTY_VMANAGER_MODE_USER
125 } VmMode;
126
127
128 typedef enum 
129 {
130         DSPROPERTY_VMANAGER_STATE_PLAYING3DHW = 0,
131         DSPROPERTY_VMANAGER_STATE_SILENT,
132         DSPROPERTY_VMANAGER_STATE_BUMPED,
133         DSPROPERTY_VMANAGER_STATE_PLAYFAILED
134 } VmState;
135
136
137 extern LPDIRECTSOUND pDirectSound;
138
139 int DS3D_inited = FALSE;
140
141 LPDIRECTSOUND3DLISTENER pDS3D_listener = NULL;
142
143 GUID DSPROPSETID_VoiceManager_Def = {0x62a69bae, 0xdf9d, 0x11d1, {0x99, 0xa6, 0x0, 0xc0, 0x4f, 0xc9, 0x9d, 0x46}};
144
145 // ---------------------------------------------------------------------------------------
146 // ds3d_update_buffer()
147 //
148 //      parameters:             channel => identifies the 3D sound to update
149 //                                              min             =>      the distance at which sound doesn't get any louder
150 //                                              max             =>      the distance at which sound doesn't attenuate any further
151 //                                              pos             => world position of sound
152 //                                              vel             => velocity of the objects producing the sound
153 //
154 //      returns:                0               =>              success
155 //                                      -1              =>              failure
156 //
157 //
158 int ds3d_update_buffer(int channel, float min, float max, vector *pos, vector *vel)
159 {
160         HRESULT                                         hr;
161         LPDIRECTSOUND3DBUFFER   pds3db;
162         float                                                   max_dist, min_dist;
163
164         if (DS3D_inited == FALSE)
165                 return 0;
166
167         if ( channel == -1 )
168                 return 0;
169
170         pds3db = Channels[channel].pds3db;
171         Assert( pds3db != NULL);
172
173         // set the buffer position
174         if ( pos != NULL ) {
175                 hr = pds3db->SetPosition(pos->x, pos->y, pos->z, DS3D_DEFERRED);
176         }
177
178         // set the buffer veclocity
179         if ( vel != NULL ) {
180                 hr = pds3db->SetVelocity(vel->x, vel->y, vel->z, DS3D_DEFERRED);
181         }
182         else {
183                 hr = pds3db->SetVelocity(0.0f, 0.0f, 0.0f, DS3D_DEFERRED);
184         }
185
186         // set the min distance
187         hr = pds3db->GetMinDistance(&min_dist);
188         hr = pds3db->SetMinDistance( min, DS3D_DEFERRED );
189         // set the max distance
190         hr = pds3db->GetMaxDistance(&max_dist);
191 //      hr = pds3db->SetMaxDistance( max, DS3D_DEFERRED );
192         hr = pds3db->SetMaxDistance( 100000.0f, DS3D_DEFERRED );
193
194         return 0;
195 }
196
197
198 // ---------------------------------------------------------------------------------------
199 // ds3d_update_listener()
200 //
201 //      returns:                0               =>              success
202 //                                      -1              =>              failure
203 //
204 int ds3d_update_listener(vector *pos, vector *vel, matrix *orient)
205 {
206         HRESULT                 hr;
207
208         if (DS3D_inited == FALSE)
209                 return 0;
210
211         if ( pDS3D_listener == NULL )
212                 return -1;
213         
214         // set the listener position
215         if ( pos != NULL ) {
216                 hr = pDS3D_listener->SetPosition(pos->x, pos->y, pos->z, DS3D_DEFERRED); 
217         }
218
219         // set the listener veclocity
220         if ( vel != NULL ) {
221                 hr = pDS3D_listener->SetVelocity(vel->x, vel->y, vel->z, DS3D_DEFERRED); 
222         }
223
224         if ( orient != NULL ) {
225                 hr = pDS3D_listener->SetOrientation(    orient->fvec.x, orient->fvec.y, orient->fvec.z,
226                                                                                                                         orient->uvec.x, orient->uvec.y, orient->uvec.z,
227                                                                                                                         DS3D_DEFERRED );
228         }
229
230         float rolloff_factor = 1.0f;
231         if (ds_using_a3d() == true) {
232                 rolloff_factor = 3.0f;          // A3D rolloff
233         } else {
234                 rolloff_factor = 3.0f;          // EAX rolloff
235         }
236
237         hr = pDS3D_listener->SetRolloffFactor( rolloff_factor, DS3D_DEFERRED );
238         hr = pDS3D_listener->SetDopplerFactor( 1.0f, DS3D_DEFERRED );
239         
240         hr = pDS3D_listener->CommitDeferredSettings();
241         if ( hr != DS_OK ) {
242                 nprintf(("SOUND","Error in pDS3D_listener->CommitDeferredSettings(): %s\n", get_DSERR_text(hr) ));
243                 return -1;
244         }
245
246         return 0;
247 }
248
249 // ---------------------------------------------------------------------------------------
250 // ds3d_init_listener()
251 //
252 //
253 //      returns:                0               =>              success
254 //                                      -1              =>              failure
255 //
256 int ds3d_init_listener()
257 {
258         HRESULT                 hr;
259
260         if ( pDS3D_listener != NULL )
261                 return 0;
262
263         hr = pPrimaryBuffer->QueryInterface(IID_IDirectSound3DListener, (void**)&pDS3D_listener);
264         if (hr != DS_OK) {
265                 nprintf(("Sound","SOUND => Fatal error calling pPrimaryBuffer->QueryInterface(): %s\n", get_DSERR_text(hr) ));
266                 return -1;
267         }
268
269         return 0;               
270 }
271
272 // ---------------------------------------------------------------------------------------
273 // ds3d_close_listener()
274 //
275 //
276 void ds3d_close_listener()
277 {
278         if ( pDS3D_listener != NULL ) {
279                 pDS3D_listener->Release();
280                 pDS3D_listener = NULL;
281         }
282 }
283
284
285 // ---------------------------------------------------------------------------------------
286 // ds3d_init()
287 //
288 // Initialize the DirectSound3D system.  Call the initalization for the pDS3D_listener
289 // 
290 // returns:     -1      => init failed
291 //              0               => success
292 int ds3d_init(int voice_manager_required)
293 {
294         if ( DS3D_inited == TRUE )
295                 return 0;
296
297         if (voice_manager_required == 1) {
298                 LPKSPROPERTYSET pset;
299                 pset = (LPKSPROPERTYSET)ds_get_property_set_interface();
300
301                 if (pset == NULL) {
302                         nprintf(("Sound", "Disabling DirectSound3D since unable to get property set interface\n"));
303                         return -1;
304                 }
305
306                 HRESULT hr;
307                 unsigned long driver_support = 0;
308
309                 hr = pset->QuerySupport(DSPROPSETID_VoiceManager_Def, DSPROPERTY_VMANAGER_MODE, &driver_support);
310                 if (FAILED(hr)) {
311                         nprintf(("Sound", "Driver does not support Voice Manager extension, so abort DirectSound3D initialization\n"));
312                         return -1;
313                 }
314
315                 if ((driver_support & KSPROPERTY_SUPPORT_SET|KSPROPERTY_SUPPORT_GET) != (KSPROPERTY_SUPPORT_SET|KSPROPERTY_SUPPORT_GET)) {
316                         nprintf(("Sound", "Driver does not support Voice Manager extension, so abort DirectSound3D initialization\n"));
317                         return -1;
318                 }
319
320                 VmMode vmode = DSPROPERTY_VMANAGER_MODE_AUTO;
321                 hr = pset->Set(DSPROPSETID_VoiceManager_Def, DSPROPERTY_VMANAGER_MODE, NULL, 0, &vmode, sizeof(float));
322                 if (FAILED(hr)) {
323                         nprintf(("Sound", "Driver does not support Voice Manager extension, so abort DirectSound3D initialization\n"));
324                         return -1;
325                 }
326         }
327
328         if (ds3d_init_listener() != 0) {
329                 return -1;
330         }
331         
332         DS3D_inited = TRUE;
333         return 0;
334 }
335
336
337 // ---------------------------------------------------------------------------------------
338 // ds3d_close()
339 //
340 // De-initialize the DirectSound3D system
341 // 
342 void ds3d_close()
343 {
344         if ( DS3D_inited == FALSE )
345                 return;
346
347         ds3d_close_listener();
348         DS3D_inited = FALSE;
349 }
350