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