fdopen: don't rewind the file after creating the FILE* handle. Added
[wine] / dlls / dsound / sound3d.c
1 /*                      DirectSound
2  *
3  * Copyright 1998 Marcus Meissner
4  * Copyright 1998 Rob Riggs
5  * Copyright 2000-2001 TransGaming Technologies, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  */
21 /*
22  * Most thread locking is complete. There may be a few race
23  * conditions still lurking.
24  *
25  * Tested with a Soundblaster clone, a Gravis UltraSound Classic,
26  * and a Turtle Beach Tropez+.
27  *
28  * TODO:
29  *      Implement SetCooperativeLevel properly (need to address focus issues)
30  *      Implement DirectSound3DBuffers (stubs in place)
31  *      Use hardware 3D support if available
32  *      Add critical section locking inside Release and AddRef methods
33  *      Handle static buffers - put those in hardware, non-static not in hardware
34  *      Hardware DuplicateSoundBuffer
35  *      Proper volume calculation, and setting volume in HEL primary buffer
36  *      Optimize WINMM and negotiate fragment size, decrease DS_HEL_MARGIN
37  */
38
39 #include "config.h"
40 #include <assert.h>
41 #include <stdio.h>
42 #include <sys/types.h>
43 #include <sys/fcntl.h>
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
47 #include <stdlib.h>
48 #include <string.h>
49 #include <math.h>       /* Insomnia - pow() function */
50
51 #include "windef.h"
52 #include "winbase.h"
53 #include "wingdi.h"
54 #include "winuser.h"
55 #include "winerror.h"
56 #include "mmsystem.h"
57 #include "winternl.h"
58 #include "mmddk.h"
59 #include "wine/windef16.h"
60 #include "wine/debug.h"
61 #include "dsound.h"
62 #include "dsdriver.h"
63 #include "dsound_private.h"
64
65 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
66
67
68 /*******************************************************************************
69  *              IDirectSound3DBuffer
70  */
71
72 /* IUnknown methods */
73 static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface(
74         LPDIRECTSOUND3DBUFFER iface, REFIID riid, LPVOID *ppobj)
75 {
76         ICOM_THIS(IDirectSound3DBufferImpl,iface);
77
78         TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
79         return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
80 }
81
82 static ULONG WINAPI IDirectSound3DBufferImpl_AddRef(LPDIRECTSOUND3DBUFFER iface)
83 {
84         ICOM_THIS(IDirectSound3DBufferImpl,iface);
85         ULONG ulReturn;
86
87         TRACE("(%p) ref was %ld\n", This, This->ref);
88         ulReturn = InterlockedIncrement(&This->ref);
89         if (ulReturn == 1)
90                 IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This->dsb);
91         return ulReturn;
92 }
93
94 static ULONG WINAPI IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface)
95 {
96         ICOM_THIS(IDirectSound3DBufferImpl,iface);
97         ULONG ulReturn;
98
99         TRACE("(%p) ref was %ld\n", This, This->ref);
100
101         ulReturn = InterlockedDecrement(&This->ref);
102         if(ulReturn)
103                 return ulReturn;
104
105         if (This->dsb) {
106                 BOOL std = (This->dsb->dsbd.dwFlags & DSBCAPS_CTRL3D);
107
108                 IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
109
110                 if (std)
111                         return 0; /* leave it to IDirectSoundBufferImpl_Release */
112         }
113
114         if (This->dsb->ds3db == This) This->dsb->ds3db = NULL;
115
116         DeleteCriticalSection(&This->lock);
117
118         HeapFree(GetProcessHeap(),0,This);
119
120         return 0;
121 }
122
123 /* IDirectSound3DBuffer methods */
124 static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters(
125         LPDIRECTSOUND3DBUFFER iface,
126         LPDS3DBUFFER lpDs3dBuffer)
127 {
128         ICOM_THIS(IDirectSound3DBufferImpl,iface);
129         TRACE("returning: all parameters\n");
130         *lpDs3dBuffer = This->ds3db;
131         return DS_OK;
132 }
133
134 static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles(
135         LPDIRECTSOUND3DBUFFER iface,
136         LPDWORD lpdwInsideConeAngle,
137         LPDWORD lpdwOutsideConeAngle)
138 {
139         ICOM_THIS(IDirectSound3DBufferImpl,iface);
140         TRACE("returning: Inside Cone Angle = %ld degrees; Outside Cone Angle = %ld degrees\n", This->ds3db.dwInsideConeAngle, This->ds3db.dwOutsideConeAngle);
141         *lpdwInsideConeAngle = This->ds3db.dwInsideConeAngle;
142         *lpdwOutsideConeAngle = This->ds3db.dwOutsideConeAngle;
143         return DS_OK;
144 }
145
146 static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation(
147         LPDIRECTSOUND3DBUFFER iface,
148         LPD3DVECTOR lpvConeOrientation)
149 {
150         ICOM_THIS(IDirectSound3DBufferImpl,iface);
151         TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n", This->ds3db.vConeOrientation.u1.x, This->ds3db.vConeOrientation.u2.y, This->ds3db.vConeOrientation.u3.z);
152         *lpvConeOrientation = This->ds3db.vConeOrientation;
153         return DS_OK;
154 }
155
156 static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume(
157         LPDIRECTSOUND3DBUFFER iface,
158         LPLONG lplConeOutsideVolume)
159 {
160         ICOM_THIS(IDirectSound3DBufferImpl,iface);
161         TRACE("returning: Cone Outside Volume = %ld\n", This->ds3db.lConeOutsideVolume);
162         *lplConeOutsideVolume = This->ds3db.lConeOutsideVolume;
163         return DS_OK;
164 }
165
166 static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance(
167         LPDIRECTSOUND3DBUFFER iface,
168         LPD3DVALUE lpfMaxDistance)
169 {
170         ICOM_THIS(IDirectSound3DBufferImpl,iface);
171         TRACE("returning: Max Distance = %f\n", This->ds3db.flMaxDistance);
172         *lpfMaxDistance = This->ds3db.flMaxDistance;
173         return DS_OK;
174 }
175
176 static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance(
177         LPDIRECTSOUND3DBUFFER iface,
178         LPD3DVALUE lpfMinDistance)
179 {
180         ICOM_THIS(IDirectSound3DBufferImpl,iface);
181         TRACE("returning: Min Distance = %f\n", This->ds3db.flMinDistance);
182         *lpfMinDistance = This->ds3db.flMinDistance;
183         return DS_OK;
184 }
185
186 static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode(
187         LPDIRECTSOUND3DBUFFER iface,
188         LPDWORD lpdwMode)
189 {
190         ICOM_THIS(IDirectSound3DBufferImpl,iface);
191         TRACE("returning: Mode = %ld\n", This->ds3db.dwMode);
192         *lpdwMode = This->ds3db.dwMode;
193         return DS_OK;
194 }
195
196 static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition(
197         LPDIRECTSOUND3DBUFFER iface,
198         LPD3DVECTOR lpvPosition)
199 {
200         ICOM_THIS(IDirectSound3DBufferImpl,iface);
201         TRACE("returning: Position vector = (%f,%f,%f)\n", This->ds3db.vPosition.u1.x, This->ds3db.vPosition.u2.y, This->ds3db.vPosition.u1.x);
202         *lpvPosition = This->ds3db.vPosition;
203         return DS_OK;
204 }
205
206 static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity(
207         LPDIRECTSOUND3DBUFFER iface,
208         LPD3DVECTOR lpvVelocity)
209 {
210         ICOM_THIS(IDirectSound3DBufferImpl,iface);
211         TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->ds3db.vVelocity.u1.x, This->ds3db.vVelocity.u2.y, This->ds3db.vVelocity.u3.z);
212         *lpvVelocity = This->ds3db.vVelocity;
213         return DS_OK;
214 }
215
216 static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(
217         LPDIRECTSOUND3DBUFFER iface,
218         LPCDS3DBUFFER lpcDs3dBuffer,
219         DWORD dwApply)
220 {
221         ICOM_THIS(IDirectSound3DBufferImpl,iface);
222         TRACE("setting: all parameters; dwApply = %ld\n", dwApply);
223         This->ds3db = *lpcDs3dBuffer;
224         if (dwApply == DS3D_IMMEDIATE)
225         {
226                 FIXME("nothing happens yet...\n");
227                 /* TRACE("recalculating...\n"); */
228                 /* place function for recalculation here */
229         }
230         FIXME("DS3D_DEFERRED flag not supported yet\n");
231         return DS_OK;
232 }
233
234 static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles(
235         LPDIRECTSOUND3DBUFFER iface,
236         DWORD dwInsideConeAngle,
237         DWORD dwOutsideConeAngle,
238         DWORD dwApply)
239 {
240         ICOM_THIS(IDirectSound3DBufferImpl,iface);
241         TRACE("setting: Inside Cone Angle = %ld; Outside Cone Angle = %ld; dwApply = %ld\n", dwInsideConeAngle, dwOutsideConeAngle, dwApply);
242         This->ds3db.dwInsideConeAngle = dwInsideConeAngle;
243         This->ds3db.dwOutsideConeAngle = dwOutsideConeAngle;
244         if (dwApply == DS3D_IMMEDIATE)
245         {
246                 FIXME("nothing happens yet...\n");
247                 /* TRACE("recalculating...\n"); */
248                 /* place function for recalculation here */
249         }
250         FIXME("DS3D_DEFERRED flag not supported yet\n");
251         return DS_OK;
252 }
253
254 static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(
255         LPDIRECTSOUND3DBUFFER iface,
256         D3DVALUE x, D3DVALUE y, D3DVALUE z,
257         DWORD dwApply)
258 {
259         ICOM_THIS(IDirectSound3DBufferImpl,iface);
260         TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
261         This->ds3db.vConeOrientation.u1.x = x;
262         This->ds3db.vConeOrientation.u2.y = y;
263         This->ds3db.vConeOrientation.u3.z = z;
264         if (dwApply == DS3D_IMMEDIATE)
265         {
266                 FIXME("nothing happens yet...\n");
267                 /* TRACE("recalculating...\n"); */
268                 /* place function for recalculation here */
269         }
270         FIXME("DS3D_DEFERRED flag not supported yet\n");
271         return DS_OK;
272 }
273
274 static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(
275         LPDIRECTSOUND3DBUFFER iface,
276         LONG lConeOutsideVolume,
277         DWORD dwApply)
278 {
279         ICOM_THIS(IDirectSound3DBufferImpl,iface);
280         TRACE("setting: ConeOutsideVolume = %ld; dwApply = %ld\n", lConeOutsideVolume, dwApply);
281         This->ds3db.lConeOutsideVolume = lConeOutsideVolume;
282         if (dwApply == DS3D_IMMEDIATE)
283         {
284                 FIXME("nothing happens yet...\n");
285                 /* TRACE("recalculating...\n"); */
286                 /* place function for recalculation here */
287         }
288         FIXME("DS3D_DEFERRED flag not supported yet\n");
289         return DS_OK;
290 }
291
292 static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(
293         LPDIRECTSOUND3DBUFFER iface,
294         D3DVALUE fMaxDistance,
295         DWORD dwApply)
296 {
297         ICOM_THIS(IDirectSound3DBufferImpl,iface);
298         TRACE("setting: MaxDistance = %f; dwApply = %ld\n", fMaxDistance, dwApply);
299         This->ds3db.flMaxDistance = fMaxDistance;
300         if (dwApply == DS3D_IMMEDIATE)
301         {
302                 FIXME("nothing happens yet...\n");
303                 /* TRACE("recalculating...\n"); */
304                 /* place function for recalculation here */
305         }
306         FIXME("DS3D_DEFERRED flag not supported yet\n");
307         return DS_OK;
308 }
309
310 static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(
311         LPDIRECTSOUND3DBUFFER iface,
312         D3DVALUE fMinDistance,
313         DWORD dwApply)
314 {
315         ICOM_THIS(IDirectSound3DBufferImpl,iface);
316         TRACE("setting: MinDistance = %f; dwApply = %ld\n", fMinDistance, dwApply);
317         This->ds3db.flMinDistance = fMinDistance;
318         if (dwApply == DS3D_IMMEDIATE)
319         {
320                 FIXME("nothing happens yet...\n");
321                 /* TRACE("recalculating...\n"); */
322                 /* place function for recalculation here */
323         }
324         FIXME("DS3D_DEFERRED flag not supported yet\n");
325         return DS_OK;
326 }
327
328 static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(
329         LPDIRECTSOUND3DBUFFER iface,
330         DWORD dwMode,
331         DWORD dwApply)
332 {
333         ICOM_THIS(IDirectSound3DBufferImpl,iface);
334         TRACE("setting: Mode = %ld; dwApply = %ld\n", dwMode, dwApply);
335         This->ds3db.dwMode = dwMode;
336         if (dwApply == DS3D_IMMEDIATE)
337         {
338                 FIXME("nothing happens yet...\n");
339                 /* TRACE("recalculating...\n"); */
340                 /* place function for recalculation here */
341         }
342         FIXME("DS3D_DEFERRED flag not supported yet\n");
343         return DS_OK;
344 }
345
346 static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(
347         LPDIRECTSOUND3DBUFFER iface,
348         D3DVALUE x, D3DVALUE y, D3DVALUE z,
349         DWORD dwApply)
350 {
351         ICOM_THIS(IDirectSound3DBufferImpl,iface);
352         TRACE("setting: Position vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
353         This->ds3db.vPosition.u1.x = x;
354         This->ds3db.vPosition.u2.y = y;
355         This->ds3db.vPosition.u3.z = z;
356         if (dwApply == DS3D_IMMEDIATE)
357         {
358                 FIXME("nothing happens yet...\n");
359                 /* TRACE("recalculating...\n"); */
360                 /* place function for recalculation here */
361         }
362         FIXME("DS3D_DEFERRED flag not supported yet\n");
363         return DS_OK;
364 }
365
366 static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(
367         LPDIRECTSOUND3DBUFFER iface,
368         D3DVALUE x, D3DVALUE y, D3DVALUE z,
369         DWORD dwApply)
370 {
371         ICOM_THIS(IDirectSound3DBufferImpl,iface);
372         TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
373         This->ds3db.vVelocity.u1.x = x;
374         This->ds3db.vVelocity.u2.y = y;
375         This->ds3db.vVelocity.u3.z = z;
376         if (dwApply == DS3D_IMMEDIATE)
377         {
378                 FIXME("nothing happens yet...\n");
379                 /* TRACE("recalculating...\n"); */
380                 /* place function for recalculation here */
381         }
382         FIXME("DS3D_DEFERRED flag not supported yet\n");
383         return DS_OK;
384 }
385
386 static ICOM_VTABLE(IDirectSound3DBuffer) ds3dbvt =
387 {
388         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
389         /* IUnknown methods */
390         IDirectSound3DBufferImpl_QueryInterface,
391         IDirectSound3DBufferImpl_AddRef,
392         IDirectSound3DBufferImpl_Release,
393         /* IDirectSound3DBuffer methods */
394         IDirectSound3DBufferImpl_GetAllParameters,
395         IDirectSound3DBufferImpl_GetConeAngles,
396         IDirectSound3DBufferImpl_GetConeOrientation,
397         IDirectSound3DBufferImpl_GetConeOutsideVolume,
398         IDirectSound3DBufferImpl_GetMaxDistance,
399         IDirectSound3DBufferImpl_GetMinDistance,
400         IDirectSound3DBufferImpl_GetMode,
401         IDirectSound3DBufferImpl_GetPosition,
402         IDirectSound3DBufferImpl_GetVelocity,
403         IDirectSound3DBufferImpl_SetAllParameters,
404         IDirectSound3DBufferImpl_SetConeAngles,
405         IDirectSound3DBufferImpl_SetConeOrientation,
406         IDirectSound3DBufferImpl_SetConeOutsideVolume,
407         IDirectSound3DBufferImpl_SetMaxDistance,
408         IDirectSound3DBufferImpl_SetMinDistance,
409         IDirectSound3DBufferImpl_SetMode,
410         IDirectSound3DBufferImpl_SetPosition,
411         IDirectSound3DBufferImpl_SetVelocity,
412 };
413
414 HRESULT WINAPI IDirectSound3DBufferImpl_Create(
415         IDirectSoundBufferImpl *This,
416         IDirectSound3DBufferImpl **pds3db)
417 {
418         IDirectSound3DBufferImpl *ds3db;
419
420         ds3db = (IDirectSound3DBufferImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*ds3db));
421         ds3db->ref = 0;
422         ds3db->dsb = This;
423         ICOM_VTBL(ds3db) = &ds3dbvt;
424         InitializeCriticalSection(&ds3db->lock);
425
426         ds3db->ds3db.dwSize = sizeof(DS3DBUFFER);
427         ds3db->ds3db.vPosition.u1.x = 0.0;
428         ds3db->ds3db.vPosition.u2.y = 0.0;
429         ds3db->ds3db.vPosition.u3.z = 0.0;
430         ds3db->ds3db.vVelocity.u1.x = 0.0;
431         ds3db->ds3db.vVelocity.u2.y = 0.0;
432         ds3db->ds3db.vVelocity.u3.z = 0.0;
433         ds3db->ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
434         ds3db->ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
435         ds3db->ds3db.vConeOrientation.u1.x = 0.0;
436         ds3db->ds3db.vConeOrientation.u2.y = 0.0;
437         ds3db->ds3db.vConeOrientation.u3.z = 0.0;
438         ds3db->ds3db.lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME;
439         ds3db->ds3db.flMinDistance = DS3D_DEFAULTMINDISTANCE;
440         ds3db->ds3db.flMaxDistance = DS3D_DEFAULTMAXDISTANCE;
441         ds3db->ds3db.dwMode = DS3DMODE_NORMAL;
442
443         *pds3db = ds3db;
444         return S_OK;
445 }
446
447 /*******************************************************************************
448  *            IDirectSound3DListener
449  */
450
451 /* IUnknown methods */
452 static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface(
453         LPDIRECTSOUND3DLISTENER iface, REFIID riid, LPVOID *ppobj)
454 {
455         ICOM_THIS(IDirectSound3DListenerImpl,iface);
456
457         TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
458         return IDirectSoundBuffer_QueryInterface((LPDIRECTSOUNDBUFFER8)This->dsb, riid, ppobj);
459 }
460
461 static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface)
462 {
463         ICOM_THIS(IDirectSound3DListenerImpl,iface);
464         return InterlockedIncrement(&This->ref);
465 }
466
467 static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER iface)
468 {
469         ICOM_THIS(IDirectSound3DListenerImpl,iface);
470         ULONG ulReturn;
471
472         TRACE("(%p) ref was %ld\n", This, This->ref);
473
474         ulReturn = InterlockedDecrement(&This->ref);
475
476         /* Free all resources */
477         if( ulReturn == 0 ) {
478                 if(This->dsb)
479                         IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
480                 DeleteCriticalSection(&This->lock);
481                 HeapFree(GetProcessHeap(),0,This);
482         }
483
484         return ulReturn;
485 }
486
487 /* IDirectSound3DListener methods */
488 static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter(
489         LPDIRECTSOUND3DLISTENER iface,
490         LPDS3DLISTENER lpDS3DL)
491 {
492         ICOM_THIS(IDirectSound3DListenerImpl,iface);
493         TRACE("returning: all parameters\n");
494         *lpDS3DL = This->ds3dl;
495         return DS_OK;
496 }
497
498 static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor(
499         LPDIRECTSOUND3DLISTENER iface,
500         LPD3DVALUE lpfDistanceFactor)
501 {
502         ICOM_THIS(IDirectSound3DListenerImpl,iface);
503         TRACE("returning: Distance Factor = %f\n", This->ds3dl.flDistanceFactor);
504         *lpfDistanceFactor = This->ds3dl.flDistanceFactor;
505         return DS_OK;
506 }
507
508 static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor(
509         LPDIRECTSOUND3DLISTENER iface,
510         LPD3DVALUE lpfDopplerFactor)
511 {
512         ICOM_THIS(IDirectSound3DListenerImpl,iface);
513         TRACE("returning: Doppler Factor = %f\n", This->ds3dl.flDopplerFactor);
514         *lpfDopplerFactor = This->ds3dl.flDopplerFactor;
515         return DS_OK;
516 }
517
518 static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation(
519         LPDIRECTSOUND3DLISTENER iface,
520         LPD3DVECTOR lpvOrientFront,
521         LPD3DVECTOR lpvOrientTop)
522 {
523         ICOM_THIS(IDirectSound3DListenerImpl,iface);
524         TRACE("returning: OrientFront vector = (%f,%f,%f); OrientTop vector = (%f,%f,%f)\n", This->ds3dl.vOrientFront.u1.x, \
525         This->ds3dl.vOrientFront.u2.y, This->ds3dl.vOrientFront.u3.z, This->ds3dl.vOrientTop.u1.x, This->ds3dl.vOrientTop.u2.y, \
526         This->ds3dl.vOrientTop.u3.z);
527         *lpvOrientFront = This->ds3dl.vOrientFront;
528         *lpvOrientTop = This->ds3dl.vOrientTop;
529         return DS_OK;
530 }
531
532 static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition(
533         LPDIRECTSOUND3DLISTENER iface,
534         LPD3DVECTOR lpvPosition)
535 {
536         ICOM_THIS(IDirectSound3DListenerImpl,iface);
537         TRACE("returning: Position vector = (%f,%f,%f)\n", This->ds3dl.vPosition.u1.x, This->ds3dl.vPosition.u2.y, This->ds3dl.vPosition.u3.z);
538         *lpvPosition = This->ds3dl.vPosition;
539         return DS_OK;
540 }
541
542 static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor(
543         LPDIRECTSOUND3DLISTENER iface,
544         LPD3DVALUE lpfRolloffFactor)
545 {
546         ICOM_THIS(IDirectSound3DListenerImpl,iface);
547         TRACE("returning: RolloffFactor = %f\n", This->ds3dl.flRolloffFactor);
548         *lpfRolloffFactor = This->ds3dl.flRolloffFactor;
549         return DS_OK;
550 }
551
552 static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity(
553         LPDIRECTSOUND3DLISTENER iface,
554         LPD3DVECTOR lpvVelocity)
555 {
556         ICOM_THIS(IDirectSound3DListenerImpl,iface);
557         TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->ds3dl.vVelocity.u1.x, This->ds3dl.vVelocity.u2.y, This->ds3dl.vVelocity.u3.z);
558         *lpvVelocity = This->ds3dl.vVelocity;
559         return DS_OK;
560 }
561
562 static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters(
563         LPDIRECTSOUND3DLISTENER iface,
564         LPCDS3DLISTENER lpcDS3DL,
565         DWORD dwApply)
566 {
567         ICOM_THIS(IDirectSound3DListenerImpl,iface);
568         TRACE("setting: all parameters; dwApply = %ld\n", dwApply);
569         This->ds3dl = *lpcDS3DL;
570         if (dwApply == DS3D_IMMEDIATE)
571         {
572                 FIXME("nothing happens yet...\n");
573                 /* TRACE("recalculating...\n"); */
574                 /* place function for recalculation here */
575         }
576         FIXME("DS3D_DEFERRED flag not supported yet\n");
577         return DS_OK;
578 }
579
580 static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor(
581         LPDIRECTSOUND3DLISTENER iface,
582         D3DVALUE fDistanceFactor,
583         DWORD dwApply)
584 {
585         ICOM_THIS(IDirectSound3DListenerImpl,iface);
586         TRACE("setting: Distance Factor = %f; dwApply = %ld\n", fDistanceFactor, dwApply);
587         This->ds3dl.flDistanceFactor = fDistanceFactor;
588         if (dwApply == DS3D_IMMEDIATE)
589         {
590                 FIXME("nothing happens yet...\n");
591                 /* TRACE("recalculating...\n"); */
592                 /* place function for recalculation here */
593         }
594         FIXME("DS3D_DEFERRED flag not supported yet\n");
595         return DS_OK;
596 }
597
598 static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor(
599         LPDIRECTSOUND3DLISTENER iface,
600         D3DVALUE fDopplerFactor,
601         DWORD dwApply)
602 {
603         ICOM_THIS(IDirectSound3DListenerImpl,iface);
604         TRACE("setting: Doppler Factor = %f; dwApply = %ld\n", fDopplerFactor, dwApply);
605         This->ds3dl.flDopplerFactor = fDopplerFactor;
606         if (dwApply == DS3D_IMMEDIATE)
607         {
608                 FIXME("nothing happens yet...\n");
609                 /* TRACE("recalculating...\n"); */
610                 /* place function for recalculation here */
611         }
612         FIXME("DS3D_DEFERRED flag not supported yet\n");
613         return DS_OK;
614 }
615
616 static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation(
617         LPDIRECTSOUND3DLISTENER iface,
618         D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront,
619         D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop,
620         DWORD dwApply)
621 {
622         ICOM_THIS(IDirectSound3DListenerImpl,iface);
623         TRACE("setting: Front vector = (%f,%f,%f); Top vector = (%f,%f,%f); dwApply = %ld\n", \
624         xFront, yFront, zFront, xTop, yTop, zTop, dwApply);
625         This->ds3dl.vOrientFront.u1.x = xFront;
626         This->ds3dl.vOrientFront.u2.y = yFront;
627         This->ds3dl.vOrientFront.u3.z = zFront;
628         This->ds3dl.vOrientTop.u1.x = xTop;
629         This->ds3dl.vOrientTop.u2.y = yTop;
630         This->ds3dl.vOrientTop.u3.z = zTop;
631         if (dwApply == DS3D_IMMEDIATE)
632         {
633                 FIXME("nothing happens yet...\n");
634                 /* TRACE("recalculating...\n"); */
635                 /* place function for recalculation here */
636         }
637         FIXME("DS3D_DEFERRED flag not supported yet\n");
638         return DS_OK;
639 }
640
641 static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition(
642         LPDIRECTSOUND3DLISTENER iface,
643         D3DVALUE x, D3DVALUE y, D3DVALUE z,
644         DWORD dwApply)
645 {
646         ICOM_THIS(IDirectSound3DListenerImpl,iface);
647         TRACE("setting: Position vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
648         This->ds3dl.vPosition.u1.x = x;
649         This->ds3dl.vPosition.u2.y = y;
650         This->ds3dl.vPosition.u3.z = z;
651         if (dwApply == DS3D_IMMEDIATE)
652         {
653                 FIXME("nothing happens yet...\n");
654                 /* TRACE("recalculating...\n"); */
655                 /* place function for recalculation here */
656         }
657         FIXME("DS3D_DEFERRED flag not supported yet\n");
658         return DS_OK;
659 }
660
661 static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor(
662         LPDIRECTSOUND3DLISTENER iface,
663         D3DVALUE fRolloffFactor,
664         DWORD dwApply)
665 {
666         ICOM_THIS(IDirectSound3DListenerImpl,iface);
667         TRACE("setting: Rolloff Factor = %f; dwApply = %ld\n", fRolloffFactor, dwApply);
668         This->ds3dl.flRolloffFactor = fRolloffFactor;
669         if (dwApply == DS3D_IMMEDIATE)
670         {
671                 FIXME("nothing happens yet...\n");
672                 /* TRACE("recalculating...\n"); */
673                 /* place function for recalculation here */
674         }
675         FIXME("DS3D_DEFERRED flag not supported yet\n");
676         return DS_OK;
677 }
678
679 static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity(
680         LPDIRECTSOUND3DLISTENER iface,
681         D3DVALUE x, D3DVALUE y, D3DVALUE z,
682         DWORD dwApply)
683 {
684         ICOM_THIS(IDirectSound3DListenerImpl,iface);
685         TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
686         This->ds3dl.vVelocity.u1.x = x;
687         This->ds3dl.vVelocity.u2.y = y;
688         This->ds3dl.vVelocity.u3.z = z;
689         if (dwApply == DS3D_IMMEDIATE)
690         {
691                 FIXME("nothing happens yet...\n");
692                 /* TRACE("recalculating...\n"); */
693                 /* place function for recalculation here */
694         }
695         FIXME("DS3D_DEFERRED flag not supported yet\n");
696         return DS_OK;
697 }
698
699 static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings(
700         LPDIRECTSOUND3DLISTENER iface)
701
702 {
703         FIXME("stub; deferred settings not used yet\n");
704         return DS_OK;
705 }
706
707 static ICOM_VTABLE(IDirectSound3DListener) ds3dlvt =
708 {
709         ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
710         /* IUnknown methods */
711         IDirectSound3DListenerImpl_QueryInterface,
712         IDirectSound3DListenerImpl_AddRef,
713         IDirectSound3DListenerImpl_Release,
714         /* IDirectSound3DListener methods */
715         IDirectSound3DListenerImpl_GetAllParameter,
716         IDirectSound3DListenerImpl_GetDistanceFactor,
717         IDirectSound3DListenerImpl_GetDopplerFactor,
718         IDirectSound3DListenerImpl_GetOrientation,
719         IDirectSound3DListenerImpl_GetPosition,
720         IDirectSound3DListenerImpl_GetRolloffFactor,
721         IDirectSound3DListenerImpl_GetVelocity,
722         IDirectSound3DListenerImpl_SetAllParameters,
723         IDirectSound3DListenerImpl_SetDistanceFactor,
724         IDirectSound3DListenerImpl_SetDopplerFactor,
725         IDirectSound3DListenerImpl_SetOrientation,
726         IDirectSound3DListenerImpl_SetPosition,
727         IDirectSound3DListenerImpl_SetRolloffFactor,
728         IDirectSound3DListenerImpl_SetVelocity,
729         IDirectSound3DListenerImpl_CommitDeferredSettings,
730 };
731
732 HRESULT WINAPI IDirectSound3DListenerImpl_Create(
733         PrimaryBufferImpl *This,
734         IDirectSound3DListenerImpl **pdsl)
735 {
736         IDirectSound3DListenerImpl *dsl;
737
738         dsl = (IDirectSound3DListenerImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(*dsl));
739         dsl->ref = 1;
740         ICOM_VTBL(dsl) = &ds3dlvt;
741
742         dsl->ds3dl.dwSize = sizeof(DS3DLISTENER);
743         dsl->ds3dl.vPosition.u1.x = 0.0;
744         dsl->ds3dl.vPosition.u2.y = 0.0;
745         dsl->ds3dl.vPosition.u3.z = 0.0;
746         dsl->ds3dl.vVelocity.u1.x = 0.0;
747         dsl->ds3dl.vVelocity.u2.y = 0.0;
748         dsl->ds3dl.vVelocity.u3.z = 0.0;
749         dsl->ds3dl.vOrientFront.u1.x = 0.0;
750         dsl->ds3dl.vOrientFront.u2.y = 0.0;
751         dsl->ds3dl.vOrientFront.u3.z = 1.0;
752         dsl->ds3dl.vOrientTop.u1.x = 0.0;
753         dsl->ds3dl.vOrientTop.u2.y = 1.0;
754         dsl->ds3dl.vOrientTop.u3.z = 0.0;
755         dsl->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
756         dsl->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
757
758         InitializeCriticalSection(&dsl->lock);
759
760         dsl->dsb = This;
761         IDirectSoundBuffer8_AddRef((LPDIRECTSOUNDBUFFER8)This);
762
763         *pdsl = dsl;
764         return S_OK;
765 }