2002-06-13 21:15:06 +02:00
/* DirectSound
*
* Copyright 1998 Marcus Meissner
* Copyright 1998 Rob Riggs
* Copyright 2000 - 2001 TransGaming Technologies , Inc .
2003-02-17 02:46:46 +01:00
* Copyright 2002 - 2003 Rok Mandeljc < rok . mandeljc @ gimb . org >
2002-06-13 21:15:06 +02:00
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
/*
* Most thread locking is complete . There may be a few race
* conditions still lurking .
*
* Tested with a Soundblaster clone , a Gravis UltraSound Classic ,
* and a Turtle Beach Tropez + .
*
* TODO :
* Implement SetCooperativeLevel properly ( need to address focus issues )
* Implement DirectSound3DBuffers ( stubs in place )
* Use hardware 3 D support if available
* Add critical section locking inside Release and AddRef methods
* Handle static buffers - put those in hardware , non - static not in hardware
* Hardware DuplicateSoundBuffer
* Proper volume calculation , and setting volume in HEL primary buffer
* Optimize WINMM and negotiate fragment size , decrease DS_HEL_MARGIN
*/
# include "config.h"
# include <assert.h>
# include <stdio.h>
# include <sys/types.h>
# include <sys/fcntl.h>
2002-08-17 02:43:16 +02:00
# ifdef HAVE_UNISTD_H
# include <unistd.h>
# endif
2002-06-13 21:15:06 +02:00
# include <stdlib.h>
# include <string.h>
# include <math.h> /* Insomnia - pow() function */
2003-01-07 21:36:20 +01:00
# define NONAMELESSUNION
# define NONAMELESSSTRUCT
2002-06-13 21:15:06 +02:00
# include "windef.h"
# include "winbase.h"
# include "wingdi.h"
# include "winuser.h"
# include "winerror.h"
# include "mmsystem.h"
2002-09-13 00:07:02 +02:00
# include "winternl.h"
2002-06-13 21:15:06 +02:00
# include "mmddk.h"
# include "wine/windef16.h"
# include "wine/debug.h"
# include "dsound.h"
# include "dsdriver.h"
# include "dsound_private.h"
2003-02-17 02:46:46 +01:00
/* default intensity level for human ears */
# define DEFAULT_INTENSITY 0.000000000001f
2003-03-31 03:34:08 +02:00
/* default velocity of sound in the air */
# define DEFAULT_VELOCITY 340
2003-02-17 02:46:46 +01:00
2003-01-04 02:24:59 +01:00
WINE_DEFAULT_DEBUG_CHANNEL ( dsound3d ) ;
2002-06-13 21:15:06 +02:00
2003-01-04 02:22:51 +01:00
/*******************************************************************************
* Auxiliary functions
*/
/* scalar product (i believe it's called dot product in english) */
static inline D3DVALUE ScalarProduct ( LPD3DVECTOR a , LPD3DVECTOR b )
{
D3DVALUE c ;
c = ( a - > u1 . x * b - > u1 . x ) + ( a - > u2 . y * b - > u2 . y ) + ( a - > u3 . z * b - > u3 . z ) ;
TRACE ( " (%f,%f,%f) * (%f,%f,%f) = %f) \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , b - > u1 . x , b - > u2 . y , \
b - > u3 . z , c ) ;
return c ;
}
/* vector product (i believe it's called cross product in english */
2003-03-10 20:06:02 +01:00
static inline D3DVECTOR VectorProduct ( LPD3DVECTOR a , LPD3DVECTOR b )
2003-01-04 02:22:51 +01:00
{
2003-03-10 20:06:02 +01:00
D3DVECTOR c ;
c . u1 . x = ( a - > u2 . y * b - > u3 . z ) - ( a - > u3 . z * b - > u2 . y ) ;
c . u2 . y = ( a - > u3 . z * b - > u1 . x ) - ( a - > u1 . x * b - > u3 . z ) ;
c . u3 . z = ( a - > u1 . x * b - > u2 . y ) - ( a - > u2 . y * b - > u1 . x ) ;
2003-01-04 02:22:51 +01:00
TRACE ( " (%f,%f,%f) x (%f,%f,%f) = (%f,%f,%f) \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , b - > u1 . x , b - > u2 . y , \
2003-03-10 20:06:02 +01:00
b - > u3 . z , c . u1 . x , c . u2 . y , c . u3 . z ) ;
2003-01-04 02:22:51 +01:00
return c ;
}
2003-07-09 04:52:57 +02:00
/* magnitude (length) of vector */
2003-01-04 02:22:51 +01:00
static inline D3DVALUE VectorMagnitude ( LPD3DVECTOR a )
{
D3DVALUE l ;
l = sqrt ( ScalarProduct ( a , a ) ) ;
TRACE ( " |(%f,%f,%f)| = %f \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , l ) ;
return l ;
}
/* conversion between radians and degrees */
2003-03-10 20:06:02 +01:00
static inline D3DVALUE RadToDeg ( D3DVALUE angle )
2003-01-04 02:22:51 +01:00
{
2003-03-10 20:06:02 +01:00
D3DVALUE newangle ;
2003-01-04 02:22:51 +01:00
newangle = angle * ( 360 / ( 2 * M_PI ) ) ;
2003-03-10 20:06:02 +01:00
TRACE ( " %f rad = %f deg \n " , angle , newangle ) ;
2003-01-04 02:22:51 +01:00
return newangle ;
}
/* conversion between degrees and radians */
2003-03-10 20:06:02 +01:00
static inline D3DVALUE DegToRad ( D3DVALUE angle )
2003-01-04 02:22:51 +01:00
{
2003-03-10 20:06:02 +01:00
D3DVALUE newangle ;
2003-01-04 02:22:51 +01:00
newangle = angle * ( 2 * M_PI / 360 ) ;
2003-03-10 20:06:02 +01:00
TRACE ( " %f deg = %f rad \n " , angle , newangle ) ;
2003-01-04 02:22:51 +01:00
return newangle ;
}
2003-03-10 20:06:02 +01:00
/* angle between vectors - deg version */
static inline D3DVALUE AngleBetweenVectorsDeg ( LPD3DVECTOR a , LPD3DVECTOR b )
2003-01-04 02:22:51 +01:00
{
2003-03-10 20:06:02 +01:00
D3DVALUE la , lb , product , angle , cos ;
2003-01-04 02:22:51 +01:00
/* definition of scalar product: a*b = |a|*|b|*cos...therefore: */
product = ScalarProduct ( a , b ) ;
la = VectorMagnitude ( a ) ;
lb = VectorMagnitude ( b ) ;
cos = product / ( la * lb ) ;
2003-03-10 20:06:02 +01:00
angle = acos ( cos ) ;
2003-01-04 02:22:51 +01:00
/* we now have angle in radians */
2003-03-10 20:06:02 +01:00
angle = RadToDeg ( angle ) ;
2003-03-31 03:34:08 +02:00
TRACE ( " angle between (%f,%f,%f) and (%f,%f,%f) = %f degrees \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , b - > u1 . x ,
2003-03-10 20:06:02 +01:00
b - > u2 . y , b - > u3 . z , angle ) ;
return angle ;
}
/* angle between vectors - rad version */
static inline D3DVALUE AngleBetweenVectorsRad ( LPD3DVECTOR a , LPD3DVECTOR b )
{
D3DVALUE la , lb , product , angle , cos ;
/* definition of scalar product: a*b = |a|*|b|*cos...therefore: */
product = ScalarProduct ( a , b ) ;
la = VectorMagnitude ( a ) ;
lb = VectorMagnitude ( b ) ;
cos = product / ( la * lb ) ;
angle = acos ( cos ) ;
2003-03-31 03:34:08 +02:00
TRACE ( " angle between (%f,%f,%f) and (%f,%f,%f) = %f radians \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , b - > u1 . x ,
2003-01-04 02:24:59 +01:00
b - > u2 . y , b - > u3 . z , angle ) ;
2003-01-04 02:22:51 +01:00
return angle ;
}
2003-01-04 02:24:59 +01:00
/* calculates vector between two points */
static inline D3DVECTOR VectorBetweenTwoPoints ( LPD3DVECTOR a , LPD3DVECTOR b )
{
D3DVECTOR c ;
c . u1 . x = b - > u1 . x - a - > u1 . x ;
c . u2 . y = b - > u2 . y - a - > u2 . y ;
c . u3 . z = b - > u3 . z - a - > u3 . z ;
2003-03-31 03:34:08 +02:00
TRACE ( " A (%f,%f,%f), B (%f,%f,%f), AB = (%f,%f,%f) \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , b - > u1 . x , b - > u2 . y ,
2003-01-04 02:24:59 +01:00
b - > u3 . z , c . u1 . x , c . u2 . y , c . u3 . z ) ;
return c ;
}
2003-06-28 00:22:15 +02:00
/* calculates the length of vector's projection on another vector */
2003-03-31 03:34:08 +02:00
static inline D3DVALUE ProjectVector ( LPD3DVECTOR a , LPD3DVECTOR p )
{
D3DVALUE prod , result ;
prod = ScalarProduct ( a , p ) ;
result = prod / VectorMagnitude ( p ) ;
TRACE ( " length projection of (%f,%f,%f) on (%f,%f,%f) = %f \n " , a - > u1 . x , a - > u2 . y , a - > u3 . z , p - > u1 . x ,
p - > u2 . y , p - > u3 . z , result ) ;
return result ;
}
2003-01-04 02:22:51 +01:00
/*******************************************************************************
* 3 D Buffer and Listener mixing
*/
2003-01-04 02:24:59 +01:00
2003-06-28 00:22:15 +02:00
void DSOUND_Calc3DBuffer ( IDirectSoundBufferImpl * dsb )
2003-01-04 02:22:51 +01:00
{
2003-01-10 02:46:36 +01:00
/* volume, at which the sound will be played after all calcs. */
2003-03-10 20:06:02 +01:00
D3DVALUE lVolume = 0 ;
2003-02-17 02:46:46 +01:00
/* intensity (used for distance related stuff) */
double flIntensity ;
double flTemp ;
2003-01-10 02:46:36 +01:00
/* stuff for distance related stuff calc. */
2003-01-04 02:24:59 +01:00
D3DVECTOR vDistance ;
2003-03-10 20:06:02 +01:00
D3DVALUE flDistance = 0 ;
/* panning related stuff */
D3DVALUE flAngle ;
D3DVECTOR vLeft ;
2003-03-31 03:34:08 +02:00
/* doppler shift related stuff */
2003-04-05 00:13:02 +02:00
#if 0
2003-03-31 03:34:08 +02:00
D3DVALUE flFreq , flBufferVel , flListenerVel ;
2003-04-05 00:13:02 +02:00
# endif
2003-06-28 00:22:15 +02:00
TRACE ( " (%p) \n " , dsb ) ;
2003-02-17 02:46:46 +01:00
2003-03-10 20:06:02 +01:00
/* initial buffer volume */
2003-06-28 00:22:15 +02:00
lVolume = dsb - > ds3db_lVolume ;
2003-01-04 02:24:59 +01:00
2003-06-28 00:22:15 +02:00
switch ( dsb - > ds3db_ds3db . dwMode )
2003-01-04 02:24:59 +01:00
{
2003-03-05 03:47:39 +01:00
case DS3DMODE_DISABLE :
2003-03-10 20:06:02 +01:00
TRACE ( " 3D processing disabled \n " ) ;
/* this one is here only to eliminate annoying warning message */
2003-06-28 00:22:15 +02:00
DSOUND_RecalcVolPan ( & dsb - > volpan ) ;
DSOUND_ForceRemix ( dsb ) ;
2003-03-05 03:47:39 +01:00
break ;
2003-01-04 02:24:59 +01:00
case DS3DMODE_NORMAL :
2003-03-05 03:47:39 +01:00
TRACE ( " Normal 3D processing mode \n " ) ;
/* we need to calculate distance between buffer and listener*/
2003-06-28 00:22:15 +02:00
vDistance = VectorBetweenTwoPoints ( & dsb - > ds3db_ds3db . vPosition , & dsb - > dsound - > ds3dl . vPosition ) ;
2003-02-17 02:46:46 +01:00
flDistance = VectorMagnitude ( & vDistance ) ;
2003-01-10 02:46:36 +01:00
break ;
2003-01-04 02:24:59 +01:00
case DS3DMODE_HEADRELATIVE :
2003-03-05 03:47:39 +01:00
TRACE ( " Head-relative 3D processing mode \n " ) ;
/* distance between buffer and listener is same as buffer's position */
2003-06-28 00:22:15 +02:00
flDistance = VectorMagnitude ( & dsb - > ds3db_ds3db . vPosition ) ;
2003-03-10 20:06:02 +01:00
break ;
}
2003-03-05 03:47:39 +01:00
2003-06-28 00:22:15 +02:00
if ( flDistance > dsb - > ds3db_ds3db . flMaxDistance )
2003-03-05 03:47:39 +01:00
{
/* some apps don't want you to hear too distant sounds... */
2003-06-28 00:22:15 +02:00
if ( dsb - > dsbd . dwFlags & DSBCAPS_MUTE3DATMAXDISTANCE )
2003-03-05 03:47:39 +01:00
{
2003-06-28 00:22:15 +02:00
dsb - > volpan . lVolume = DSBVOLUME_MIN ;
DSOUND_RecalcVolPan ( & dsb - > volpan ) ;
2003-03-05 03:47:39 +01:00
/* i guess mixing here would be a waste of power */
return ;
}
else
2003-06-28 00:22:15 +02:00
flDistance = dsb - > ds3db_ds3db . flMaxDistance ;
2003-03-05 03:47:39 +01:00
}
2003-06-28 00:22:15 +02:00
if ( flDistance < dsb - > ds3db_ds3db . flMinDistance )
flDistance = dsb - > ds3db_ds3db . flMinDistance ;
2003-03-05 03:47:39 +01:00
/* the following formula is taken from my physics book. I think it's ok for the *real* world...i hope m$ does it that way */
lVolume + = 10000 ; /* ms likes working with negative volume...i don't */
lVolume / = 1000 ; /* convert hundreths of dB into B */
/* intensity level (loudness) = log10(Intensity/DefaultIntensity)...therefore */
2003-03-10 20:06:02 +01:00
flIntensity = pow ( 10 , lVolume ) * DEFAULT_INTENSITY ;
2003-06-28 00:22:15 +02:00
flTemp = ( flDistance / dsb - > ds3db_ds3db . flMinDistance ) * ( flDistance / dsb - > ds3db_ds3db . flMinDistance ) ;
2003-03-05 03:47:39 +01:00
flIntensity / = flTemp ;
2003-03-10 20:06:02 +01:00
lVolume = log10 ( flIntensity / DEFAULT_INTENSITY ) ;
2003-03-05 03:47:39 +01:00
lVolume * = 1000 ; /* convert back to hundreths of dB */
lVolume - = 10000 ; /* we need to do it in ms way */
2003-06-28 00:22:15 +02:00
TRACE ( " dist. att: Distance = %f, MinDistance = %f => adjusting volume %ld to %f \n " , flDistance , dsb - > ds3db_ds3db . flMinDistance , dsb - > ds3db_lVolume , lVolume ) ;
2003-03-10 20:06:02 +01:00
/* conning */
/* sometimes it happens that vConeOrientation vector = (0,0,0); in this case angle is "nan" and it's useless*/
2003-06-28 00:22:15 +02:00
if ( dsb - > ds3db_ds3db . vConeOrientation . u1 . x = = 0 & & dsb - > ds3db_ds3db . vConeOrientation . u2 . y = = 0 & & dsb - > ds3db_ds3db . vConeOrientation . u3 . z = = 0 )
2003-03-10 20:06:02 +01:00
{
TRACE ( " conning: cones not set \n " ) ;
}
else
{
/* calculate angle */
2003-06-28 00:22:15 +02:00
flAngle = AngleBetweenVectorsDeg ( & dsb - > ds3db_ds3db . vConeOrientation , & vDistance ) ;
2003-03-10 20:06:02 +01:00
/* if by any chance it happens that OutsideConeAngle = InsideConeAngle (that means that conning has no effect) */
2003-06-28 00:22:15 +02:00
if ( dsb - > ds3db_ds3db . dwInsideConeAngle ! = dsb - > ds3db_ds3db . dwOutsideConeAngle )
2003-03-10 20:06:02 +01:00
{
/* my test show that for my way of calc., we need only half of angles */
2003-06-28 00:22:15 +02:00
DWORD dwInsideConeAngle = dsb - > ds3db_ds3db . dwInsideConeAngle / 2 ;
DWORD dwOutsideConeAngle = dsb - > ds3db_ds3db . dwOutsideConeAngle / 2 ;
2003-03-10 20:06:02 +01:00
/* full volume */
if ( flAngle < dwInsideConeAngle )
flAngle = dwInsideConeAngle ;
/* min (app defined) volume */
if ( flAngle > dwOutsideConeAngle )
flAngle = dwOutsideConeAngle ;
/* this probably isn't the right thing, but it's ok for the time being */
2003-06-28 00:22:15 +02:00
lVolume + = ( ( dsb - > ds3db_ds3db . lConeOutsideVolume ) / ( ( dwOutsideConeAngle ) - ( dwInsideConeAngle ) ) ) * flAngle ;
}
2003-03-10 20:06:02 +01:00
TRACE ( " conning: Angle = %f deg; InsideConeAngle(/2) = %ld deg; OutsideConeAngle(/2) = %ld deg; ConeOutsideVolume = %ld => adjusting volume to %f \n " ,
2003-06-28 00:22:15 +02:00
flAngle , dsb - > ds3db_ds3db . dwInsideConeAngle / 2 , dsb - > ds3db_ds3db . dwOutsideConeAngle / 2 , dsb - > ds3db_ds3db . lConeOutsideVolume , lVolume ) ;
2003-03-10 20:06:02 +01:00
}
2003-06-28 00:22:15 +02:00
dsb - > volpan . lVolume = lVolume ;
2003-03-10 20:06:02 +01:00
/* panning */
2003-06-28 00:22:15 +02:00
if ( dsb - > dsound - > ds3dl . vPosition . u1 . x = = dsb - > ds3db_ds3db . vPosition . u1 . x & &
dsb - > dsound - > ds3dl . vPosition . u2 . y = = dsb - > ds3db_ds3db . vPosition . u2 . y & &
dsb - > dsound - > ds3dl . vPosition . u3 . z = = dsb - > ds3db_ds3db . vPosition . u3 . z ) {
dsb - > volpan . lPan = 0 ;
flAngle = 0.0 ;
}
else
{
vDistance = VectorBetweenTwoPoints ( & dsb - > dsound - > ds3dl . vPosition , & dsb - > ds3db_ds3db . vPosition ) ;
vLeft = VectorProduct ( & dsb - > dsound - > ds3dl . vOrientFront , & dsb - > dsound - > ds3dl . vOrientTop ) ;
flAngle = AngleBetweenVectorsRad ( & vLeft , & vDistance ) ;
/* for now, we'll use "linear formula" (which is probably incorrect); if someone has it in book, correct it */
dsb - > volpan . lPan = 10000 * 2 * flAngle / M_PI - 10000 ;
}
TRACE ( " panning: Angle = %f rad, lPan = %ld \n " , flAngle , dsb - > volpan . lPan ) ;
2003-03-31 03:34:08 +02:00
/* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */
#if 0
2003-03-10 20:06:02 +01:00
/* doppler shift*/
2003-06-28 00:22:15 +02:00
if ( ( VectorMagnitude ( & ds3db . vVelocity ) = = 0 ) & & ( VectorMagnitude ( & dsb - > dsound - > ds3dl . vVelocity ) = = 0 ) )
2003-03-31 03:34:08 +02:00
{
TRACE ( " doppler: Buffer and Listener don't have velocities \n " ) ;
}
else
{
2003-07-09 04:52:57 +02:00
/* calculate length of ds3db.vVelocity component which causes Doppler Effect
2003-03-31 03:34:08 +02:00
NOTE : if buffer moves TOWARDS the listener , it ' s velocity component is NEGATIVE
if buffer moves AWAY from listener , it ' s velocity component is POSITIVE */
2003-06-28 00:22:15 +02:00
flBufferVel = ProjectVector ( & dsb - > ds3db_ds3db . vVelocity , & vDistance ) ;
2003-07-09 04:52:57 +02:00
/* calculate length of ds3dl.vVelocity component which causes Doppler Effect
2003-03-31 03:34:08 +02:00
NOTE : if listener moves TOWARDS the buffer , it ' s velocity component is POSITIVE
if listener moves AWAY from buffer , it ' s velocity component is NEGATIVE */
2003-06-28 00:22:15 +02:00
flListenerVel = ProjectVector ( & dsb - > dsound - > ds3dl . vVelocity , & vDistance ) ;
2003-03-31 03:34:08 +02:00
/* formula taken from Gianicoli D.: Physics, 4th edition: */
2003-06-28 00:22:15 +02:00
/* FIXME: replace dsb->freq with appropriate frequency ! */
flFreq = dsb - > freq * ( ( DEFAULT_VELOCITY + flListenerVel ) / ( DEFAULT_VELOCITY + flBufferVel ) ) ;
2003-03-31 03:34:08 +02:00
TRACE ( " doppler: Buffer velocity (component) = %lf, Listener velocity (component) = %lf => Doppler shift: %ld Hz -> %lf Hz \n " , flBufferVel , flListenerVel , \
2003-06-28 00:22:15 +02:00
dsb - > freq , flFreq ) ;
2003-03-31 03:34:08 +02:00
/* FIXME: replace following line with correct frequency setting ! */
2003-06-28 00:22:15 +02:00
dsb - > freq = flFreq ;
2003-03-31 03:34:08 +02:00
}
# endif
2003-03-10 20:06:02 +01:00
2003-03-31 03:34:08 +02:00
/* time for remix */
2003-06-28 00:22:15 +02:00
DSOUND_RecalcVolPan ( & dsb - > volpan ) ;
}
static void DSOUND_Mix3DBuffer ( IDirectSoundBufferImpl * dsb )
{
TRACE ( " (%p) \n " , dsb ) ;
DSOUND_Calc3DBuffer ( dsb ) ;
DSOUND_ForceRemix ( dsb ) ;
2003-01-04 02:22:51 +01:00
}
static void WINAPI DSOUND_ChangeListener ( IDirectSound3DListenerImpl * ds3dl )
{
int i ;
2003-05-22 05:39:13 +02:00
TRACE ( " (%p) \n " , ds3dl ) ;
2003-06-28 00:22:15 +02:00
for ( i = 0 ; i < ds3dl - > dsound - > nrofbuffers ; i + + )
2003-01-04 02:22:51 +01:00
{
2003-01-04 02:24:59 +01:00
/* some buffers don't have 3d buffer (Ultima IX seems to
crash without the following line ) */
2003-06-28 00:22:15 +02:00
if ( ds3dl - > dsound - > buffers [ i ] - > ds3db = = NULL )
2003-01-04 02:24:59 +01:00
continue ;
2003-06-28 00:22:15 +02:00
if ( ds3dl - > dsound - > buffers [ i ] - > ds3db_need_recalc = = TRUE )
2003-01-04 02:24:59 +01:00
{
2003-06-28 00:22:15 +02:00
DSOUND_Mix3DBuffer ( ds3dl - > dsound - > buffers [ i ] ) ;
2003-01-04 02:24:59 +01:00
}
2003-01-04 02:22:51 +01:00
}
}
2002-06-13 21:15:06 +02:00
/*******************************************************************************
* IDirectSound3DBuffer
*/
/* IUnknown methods */
static HRESULT WINAPI IDirectSound3DBufferImpl_QueryInterface (
LPDIRECTSOUND3DBUFFER iface , REFIID riid , LPVOID * ppobj )
{
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " (%p,%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
return IDirectSoundBuffer_QueryInterface ( ( LPDIRECTSOUNDBUFFER8 ) This - > dsb , riid , ppobj ) ;
}
static ULONG WINAPI IDirectSound3DBufferImpl_AddRef ( LPDIRECTSOUND3DBUFFER iface )
{
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
ULONG ref ;
2002-06-13 21:15:06 +02:00
2003-06-28 00:22:15 +02:00
TRACE ( " (%p) ref was %ld, thread is %04lx \n " , This , This - > ref , GetCurrentThreadId ( ) ) ;
ref = InterlockedIncrement ( & This - > ref ) ;
if ( ! ref ) {
FIXME ( " thread-safety alert! AddRef-ing with a zero refcount! \n " ) ;
}
return ref ;
2002-06-13 21:15:06 +02:00
}
static ULONG WINAPI IDirectSound3DBufferImpl_Release ( LPDIRECTSOUND3DBUFFER iface )
{
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
ULONG ulReturn ;
2003-06-28 00:22:15 +02:00
TRACE ( " (%p) ref was %ld, thread is %04lx \n " , This , This - > ref , GetCurrentThreadId ( ) ) ;
2002-06-13 21:15:06 +02:00
ulReturn = InterlockedDecrement ( & This - > ref ) ;
2003-06-28 00:22:15 +02:00
if ( ! ulReturn ) {
IDirectSoundBuffer_Release ( ( LPDIRECTSOUNDBUFFER8 ) This ) ;
This - > dsb - > ds3db = NULL ;
DeleteCriticalSection ( & ( This - > lock ) ) ;
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
2002-06-13 21:15:06 +02:00
}
2003-06-28 00:22:15 +02:00
return ulReturn ;
2002-06-13 21:15:06 +02:00
}
/* IDirectSound3DBuffer methods */
static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters (
LPDIRECTSOUND3DBUFFER iface ,
LPDS3DBUFFER lpDs3dBuffer )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " (%p,%p) \n " , This , lpDs3dBuffer ) ;
if ( lpDs3dBuffer = = NULL ) {
2003-07-02 06:37:26 +02:00
WARN ( " invalid parameter: lpDs3dBuffer == NULL \n " ) ;
2003-06-28 00:22:15 +02:00
return DSERR_INVALIDPARAM ;
}
if ( lpDs3dBuffer - > dwSize < sizeof ( * lpDs3dBuffer ) ) {
2003-07-02 06:37:26 +02:00
WARN ( " invalid parameter: lpDs3dBuffer->dwSize = %ld < %d \n " , lpDs3dBuffer - > dwSize , sizeof ( * lpDs3dBuffer ) ) ;
2003-06-28 00:22:15 +02:00
return DSERR_INVALIDPARAM ;
}
if ( This - > dsb ) {
TRACE ( " returning: all parameters \n " ) ;
* lpDs3dBuffer = This - > dsb - > ds3db_ds3db ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles (
LPDIRECTSOUND3DBUFFER iface ,
LPDWORD lpdwInsideConeAngle ,
LPDWORD lpdwOutsideConeAngle )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Inside Cone Angle = %ld degrees; Outside Cone Angle = %ld degrees \n " ,
This - > dsb - > ds3db_ds3db . dwInsideConeAngle , This - > dsb - > ds3db_ds3db . dwOutsideConeAngle ) ;
* lpdwInsideConeAngle = This - > dsb - > ds3db_ds3db . dwInsideConeAngle ;
* lpdwOutsideConeAngle = This - > dsb - > ds3db_ds3db . dwOutsideConeAngle ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation (
LPDIRECTSOUND3DBUFFER iface ,
LPD3DVECTOR lpvConeOrientation )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Cone Orientation vector = (%f,%f,%f) \n " ,
This - > dsb - > ds3db_ds3db . vConeOrientation . u1 . x ,
This - > dsb - > ds3db_ds3db . vConeOrientation . u2 . y ,
This - > dsb - > ds3db_ds3db . vConeOrientation . u3 . z ) ;
* lpvConeOrientation = This - > dsb - > ds3db_ds3db . vConeOrientation ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume (
LPDIRECTSOUND3DBUFFER iface ,
LPLONG lplConeOutsideVolume )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Cone Outside Volume = %ld \n " , This - > dsb - > ds3db_ds3db . lConeOutsideVolume ) ;
* lplConeOutsideVolume = This - > dsb - > ds3db_ds3db . lConeOutsideVolume ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance (
LPDIRECTSOUND3DBUFFER iface ,
LPD3DVALUE lpfMaxDistance )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Max Distance = %f \n " , This - > dsb - > ds3db_ds3db . flMaxDistance ) ;
* lpfMaxDistance = This - > dsb - > ds3db_ds3db . flMaxDistance ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance (
LPDIRECTSOUND3DBUFFER iface ,
LPD3DVALUE lpfMinDistance )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Min Distance = %f \n " , This - > dsb - > ds3db_ds3db . flMinDistance ) ;
* lpfMinDistance = This - > dsb - > ds3db_ds3db . flMinDistance ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode (
LPDIRECTSOUND3DBUFFER iface ,
LPDWORD lpdwMode )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Mode = %ld \n " , This - > dsb - > ds3db_ds3db . dwMode ) ;
* lpdwMode = This - > dsb - > ds3db_ds3db . dwMode ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition (
LPDIRECTSOUND3DBUFFER iface ,
LPD3DVECTOR lpvPosition )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Position vector = (%f,%f,%f) \n " ,
This - > dsb - > ds3db_ds3db . vPosition . u1 . x ,
This - > dsb - > ds3db_ds3db . vPosition . u2 . y ,
This - > dsb - > ds3db_ds3db . vPosition . u3 . z ) ;
* lpvPosition = This - > dsb - > ds3db_ds3db . vPosition ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity (
LPDIRECTSOUND3DBUFFER iface ,
LPD3DVECTOR lpvVelocity )
{
2002-12-12 23:27:15 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
TRACE ( " returning: Velocity vector = (%f,%f,%f) \n " ,
This - > dsb - > ds3db_ds3db . vVelocity . u1 . x ,
This - > dsb - > ds3db_ds3db . vVelocity . u2 . y ,
This - > dsb - > ds3db_ds3db . vVelocity . u3 . z ) ;
* lpvVelocity = This - > dsb - > ds3db_ds3db . vVelocity ;
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters (
LPDIRECTSOUND3DBUFFER iface ,
LPCDS3DBUFFER lpcDs3dBuffer ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
DWORD status = DSERR_INVALIDPARAM ;
TRACE ( " (%p,%p,%lx) \n " , iface , lpcDs3dBuffer , dwApply ) ;
if ( lpcDs3dBuffer = = NULL ) {
WARN ( " invalid parameter: lpcDs3dBuffer == NULL \n " ) ;
return status ;
2002-12-13 01:31:06 +01:00
}
2003-06-28 00:22:15 +02:00
if ( lpcDs3dBuffer - > dwSize ! = sizeof ( DS3DBUFFER ) ) {
WARN ( " invalid parameter: lpcDs3dBuffer->dwSize = %ld != %d \n " ,
lpcDs3dBuffer - > dwSize , sizeof ( DS3DBUFFER ) ) ;
return status ;
}
EnterCriticalSection ( & This - > lock ) ;
if ( This - > dsb ) {
TRACE ( " setting: all parameters; dwApply = %ld \n " , dwApply ) ;
This - > dsb - > ds3db_ds3db = * lpcDs3dBuffer ;
if ( dwApply = = DS3D_IMMEDIATE )
{
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
status = DS_OK ;
} else
WARN ( " pointer no longer valid \n " ) ;
LeaveCriticalSection ( & This - > lock ) ;
return status ;
2002-06-13 21:15:06 +02:00
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles (
LPDIRECTSOUND3DBUFFER iface ,
DWORD dwInsideConeAngle ,
DWORD dwOutsideConeAngle ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " setting: Inside Cone Angle = %ld; Outside Cone Angle = %ld; dwApply = %ld \n " ,
dwInsideConeAngle , dwOutsideConeAngle , dwApply ) ;
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . dwInsideConeAngle = dwInsideConeAngle ;
This - > dsb - > ds3db_ds3db . dwOutsideConeAngle = dwOutsideConeAngle ;
if ( dwApply = = DS3D_IMMEDIATE )
{
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation (
LPDIRECTSOUND3DBUFFER iface ,
D3DVALUE x , D3DVALUE y , D3DVALUE z ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " setting: Cone Orientation vector = (%f,%f,%f); dwApply = %ld \n " , x , y , z , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . vConeOrientation . u1 . x = x ;
This - > dsb - > ds3db_ds3db . vConeOrientation . u2 . y = y ;
This - > dsb - > ds3db_ds3db . vConeOrientation . u3 . z = z ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume (
LPDIRECTSOUND3DBUFFER iface ,
LONG lConeOutsideVolume ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " setting: ConeOutsideVolume = %ld; dwApply = %ld \n " , lConeOutsideVolume , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . lConeOutsideVolume = lConeOutsideVolume ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance (
LPDIRECTSOUND3DBUFFER iface ,
D3DVALUE fMaxDistance ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " setting: MaxDistance = %f; dwApply = %ld \n " , fMaxDistance , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . flMaxDistance = fMaxDistance ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance (
LPDIRECTSOUND3DBUFFER iface ,
D3DVALUE fMinDistance ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " setting: MinDistance = %f; dwApply = %ld \n " , fMinDistance , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . flMinDistance = fMinDistance ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode (
LPDIRECTSOUND3DBUFFER iface ,
DWORD dwMode ,
DWORD dwApply )
{
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
2002-12-13 01:31:06 +01:00
TRACE ( " setting: Mode = %ld; dwApply = %ld \n " , dwMode , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . dwMode = dwMode ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition (
LPDIRECTSOUND3DBUFFER iface ,
D3DVALUE x , D3DVALUE y , D3DVALUE z ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " setting: Position vector = (%f,%f,%f); dwApply = %ld \n " , x , y , z , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . vPosition . u1 . x = x ;
This - > dsb - > ds3db_ds3db . vPosition . u2 . y = y ;
This - > dsb - > ds3db_ds3db . vPosition . u3 . z = z ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity (
LPDIRECTSOUND3DBUFFER iface ,
D3DVALUE x , D3DVALUE y , D3DVALUE z ,
DWORD dwApply )
{
2002-12-13 01:31:06 +01:00
ICOM_THIS ( IDirectSound3DBufferImpl , iface ) ;
TRACE ( " setting: Velocity vector = (%f,%f,%f); dwApply = %ld \n " , x , y , z , dwApply ) ;
2003-06-28 00:22:15 +02:00
if ( This - > dsb ) {
This - > dsb - > ds3db_ds3db . vVelocity . u1 . x = x ;
This - > dsb - > ds3db_ds3db . vVelocity . u2 . y = y ;
This - > dsb - > ds3db_ds3db . vVelocity . u3 . z = z ;
if ( dwApply = = DS3D_IMMEDIATE )
{
This - > dsb - > ds3db_need_recalc = FALSE ;
DSOUND_Mix3DBuffer ( This - > dsb ) ;
}
This - > dsb - > ds3db_need_recalc = TRUE ;
2002-12-13 01:31:06 +01:00
}
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static ICOM_VTABLE ( IDirectSound3DBuffer ) ds3dbvt =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown methods */
IDirectSound3DBufferImpl_QueryInterface ,
IDirectSound3DBufferImpl_AddRef ,
IDirectSound3DBufferImpl_Release ,
/* IDirectSound3DBuffer methods */
IDirectSound3DBufferImpl_GetAllParameters ,
IDirectSound3DBufferImpl_GetConeAngles ,
IDirectSound3DBufferImpl_GetConeOrientation ,
IDirectSound3DBufferImpl_GetConeOutsideVolume ,
IDirectSound3DBufferImpl_GetMaxDistance ,
IDirectSound3DBufferImpl_GetMinDistance ,
IDirectSound3DBufferImpl_GetMode ,
IDirectSound3DBufferImpl_GetPosition ,
IDirectSound3DBufferImpl_GetVelocity ,
IDirectSound3DBufferImpl_SetAllParameters ,
IDirectSound3DBufferImpl_SetConeAngles ,
IDirectSound3DBufferImpl_SetConeOrientation ,
IDirectSound3DBufferImpl_SetConeOutsideVolume ,
IDirectSound3DBufferImpl_SetMaxDistance ,
IDirectSound3DBufferImpl_SetMinDistance ,
IDirectSound3DBufferImpl_SetMode ,
IDirectSound3DBufferImpl_SetPosition ,
IDirectSound3DBufferImpl_SetVelocity ,
} ;
HRESULT WINAPI IDirectSound3DBufferImpl_Create (
IDirectSoundBufferImpl * This ,
IDirectSound3DBufferImpl * * pds3db )
{
IDirectSound3DBufferImpl * ds3db ;
2003-05-22 05:39:13 +02:00
TRACE ( " (%p,%p) \n " , This , pds3db ) ;
ds3db = ( IDirectSound3DBufferImpl * ) HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * ds3db ) ) ;
if ( ds3db = = NULL ) {
WARN ( " out of memory \n " ) ;
2003-06-28 00:22:15 +02:00
* pds3db = 0 ;
2003-05-22 05:39:13 +02:00
return DSERR_OUTOFMEMORY ;
}
2002-06-13 21:15:06 +02:00
ds3db - > ref = 0 ;
ds3db - > dsb = This ;
2003-04-10 20:17:34 +02:00
ds3db - > lpVtbl = & ds3dbvt ;
2003-06-28 00:22:15 +02:00
ds3db - > dsb - > ds3db_ds3db . dwSize = sizeof ( DS3DBUFFER ) ;
ds3db - > dsb - > ds3db_ds3db . vPosition . u1 . x = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vPosition . u2 . y = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vPosition . u3 . z = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vVelocity . u1 . x = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vVelocity . u2 . y = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vVelocity . u3 . z = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . dwInsideConeAngle = DS3D_DEFAULTCONEANGLE ;
ds3db - > dsb - > ds3db_ds3db . dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE ;
ds3db - > dsb - > ds3db_ds3db . vConeOrientation . u1 . x = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vConeOrientation . u2 . y = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . vConeOrientation . u3 . z = 0.0 ;
ds3db - > dsb - > ds3db_ds3db . lConeOutsideVolume = DS3D_DEFAULTCONEOUTSIDEVOLUME ;
ds3db - > dsb - > ds3db_ds3db . flMinDistance = DS3D_DEFAULTMINDISTANCE ;
ds3db - > dsb - > ds3db_ds3db . flMaxDistance = DS3D_DEFAULTMAXDISTANCE ;
ds3db - > dsb - > ds3db_ds3db . dwMode = DS3DMODE_NORMAL ;
ds3db - > dsb - > ds3db_need_recalc = TRUE ;
InitializeCriticalSection ( & ( ds3db - > lock ) ) ;
2002-06-13 21:15:06 +02:00
* pds3db = ds3db ;
return S_OK ;
}
/*******************************************************************************
* IDirectSound3DListener
*/
/* IUnknown methods */
static HRESULT WINAPI IDirectSound3DListenerImpl_QueryInterface (
LPDIRECTSOUND3DLISTENER iface , REFIID riid , LPVOID * ppobj )
{
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " (%p,%s,%p) \n " , This , debugstr_guid ( riid ) , ppobj ) ;
2003-06-28 00:22:15 +02:00
if ( IsEqualGUID ( riid , & IID_IUnknown ) | |
IsEqualGUID ( riid , & IID_IDirectSound3DListener ) ) {
IDirectSound3DListener_AddRef ( ( LPDIRECTSOUND3DLISTENER ) This ) ;
* ppobj = This ;
return S_OK ;
}
if ( IsEqualGUID ( riid , & IID_IDirectSoundBuffer ) ) {
* ppobj = This - > dsound - > primary ;
IDirectSoundBuffer_AddRef ( ( LPDIRECTSOUNDBUFFER ) * ppobj ) ;
return S_OK ;
}
FIXME ( " Unknown IID %s \n " , debugstr_guid ( riid ) ) ;
* ppobj = NULL ;
return E_NOINTERFACE ;
2002-06-13 21:15:06 +02:00
}
static ULONG WINAPI IDirectSound3DListenerImpl_AddRef ( LPDIRECTSOUND3DLISTENER iface )
{
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
ULONG ref ;
TRACE ( " (%p) ref was %ld, thread is %04lx \n " , This , This - > ref , GetCurrentThreadId ( ) ) ;
ref = InterlockedIncrement ( & This - > ref ) ;
if ( ! ref ) {
FIXME ( " thread-safety alert! AddRef-ing with a zero refcount! \n " ) ;
}
return ref ;
2002-06-13 21:15:06 +02:00
}
static ULONG WINAPI IDirectSound3DListenerImpl_Release ( LPDIRECTSOUND3DLISTENER iface )
{
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
ULONG ulReturn ;
2003-06-28 00:22:15 +02:00
TRACE ( " (%p) ref was %ld, thread is %04lx \n " , This , This - > ref , GetCurrentThreadId ( ) ) ;
2002-06-13 21:15:06 +02:00
ulReturn = InterlockedDecrement ( & This - > ref ) ;
/* Free all resources */
if ( ulReturn = = 0 ) {
2003-06-28 00:22:15 +02:00
IDirectSound8_Release ( ( LPDIRECTSOUND8 ) This - > dsound ) ;
This - > dsound - > listener = 0 ;
2002-06-13 21:15:06 +02:00
HeapFree ( GetProcessHeap ( ) , 0 , This ) ;
}
return ulReturn ;
}
/* IDirectSound3DListener methods */
static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter (
LPDIRECTSOUND3DLISTENER iface ,
LPDS3DLISTENER lpDS3DL )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " (%p,%p) \n " , This , lpDS3DL ) ;
if ( lpDS3DL = = NULL ) {
2003-07-02 06:37:26 +02:00
WARN ( " invalid parameter: lpDS3DL == NULL \n " ) ;
2003-06-28 00:22:15 +02:00
return DSERR_INVALIDPARAM ;
}
if ( lpDS3DL - > dwSize < sizeof ( * lpDS3DL ) ) {
2003-07-02 06:37:26 +02:00
WARN ( " invalid parameter: lpDS3DL->dwSize = %ld < %d \n " , lpDS3DL - > dwSize , sizeof ( * lpDS3DL ) ) ;
2003-06-28 00:22:15 +02:00
return DSERR_INVALIDPARAM ;
}
2002-12-13 00:01:05 +01:00
TRACE ( " returning: all parameters \n " ) ;
2003-06-28 00:22:15 +02:00
* lpDS3DL = This - > dsound - > ds3dl ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor (
LPDIRECTSOUND3DLISTENER iface ,
LPD3DVALUE lpfDistanceFactor )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " returning: Distance Factor = %f \n " , This - > dsound - > ds3dl . flDistanceFactor ) ;
* lpfDistanceFactor = This - > dsound - > ds3dl . flDistanceFactor ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor (
LPDIRECTSOUND3DLISTENER iface ,
LPD3DVALUE lpfDopplerFactor )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " returning: Doppler Factor = %f \n " , This - > dsound - > ds3dl . flDopplerFactor ) ;
* lpfDopplerFactor = This - > dsound - > ds3dl . flDopplerFactor ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation (
LPDIRECTSOUND3DLISTENER iface ,
LPD3DVECTOR lpvOrientFront ,
LPD3DVECTOR lpvOrientTop )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " returning: OrientFront vector = (%f,%f,%f); OrientTop vector = (%f,%f,%f) \n " , This - > dsound - > ds3dl . vOrientFront . u1 . x , \
This - > dsound - > ds3dl . vOrientFront . u2 . y , This - > dsound - > ds3dl . vOrientFront . u3 . z , This - > dsound - > ds3dl . vOrientTop . u1 . x , This - > dsound - > ds3dl . vOrientTop . u2 . y , \
This - > dsound - > ds3dl . vOrientTop . u3 . z ) ;
* lpvOrientFront = This - > dsound - > ds3dl . vOrientFront ;
* lpvOrientTop = This - > dsound - > ds3dl . vOrientTop ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition (
LPDIRECTSOUND3DLISTENER iface ,
LPD3DVECTOR lpvPosition )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " returning: Position vector = (%f,%f,%f) \n " , This - > dsound - > ds3dl . vPosition . u1 . x , This - > dsound - > ds3dl . vPosition . u2 . y , This - > dsound - > ds3dl . vPosition . u3 . z ) ;
* lpvPosition = This - > dsound - > ds3dl . vPosition ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor (
LPDIRECTSOUND3DLISTENER iface ,
LPD3DVALUE lpfRolloffFactor )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " returning: RolloffFactor = %f \n " , This - > dsound - > ds3dl . flRolloffFactor ) ;
* lpfRolloffFactor = This - > dsound - > ds3dl . flRolloffFactor ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity (
LPDIRECTSOUND3DLISTENER iface ,
LPD3DVECTOR lpvVelocity )
{
2002-12-13 00:01:05 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
2003-06-28 00:22:15 +02:00
TRACE ( " returning: Velocity vector = (%f,%f,%f) \n " , This - > dsound - > ds3dl . vVelocity . u1 . x , This - > dsound - > ds3dl . vVelocity . u2 . y , This - > dsound - > ds3dl . vVelocity . u3 . z ) ;
* lpvVelocity = This - > dsound - > ds3dl . vVelocity ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters (
LPDIRECTSOUND3DLISTENER iface ,
LPCDS3DLISTENER lpcDS3DL ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: all parameters; dwApply = %ld \n " , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl = * lpcDS3DL ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor (
LPDIRECTSOUND3DLISTENER iface ,
D3DVALUE fDistanceFactor ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: Distance Factor = %f; dwApply = %ld \n " , fDistanceFactor , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl . flDistanceFactor = fDistanceFactor ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor (
LPDIRECTSOUND3DLISTENER iface ,
D3DVALUE fDopplerFactor ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: Doppler Factor = %f; dwApply = %ld \n " , fDopplerFactor , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl . flDopplerFactor = fDopplerFactor ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation (
LPDIRECTSOUND3DLISTENER iface ,
D3DVALUE xFront , D3DVALUE yFront , D3DVALUE zFront ,
D3DVALUE xTop , D3DVALUE yTop , D3DVALUE zTop ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: Front vector = (%f,%f,%f); Top vector = (%f,%f,%f); dwApply = %ld \n " , \
xFront , yFront , zFront , xTop , yTop , zTop , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl . vOrientFront . u1 . x = xFront ;
This - > dsound - > ds3dl . vOrientFront . u2 . y = yFront ;
This - > dsound - > ds3dl . vOrientFront . u3 . z = zFront ;
This - > dsound - > ds3dl . vOrientTop . u1 . x = xTop ;
This - > dsound - > ds3dl . vOrientTop . u2 . y = yTop ;
This - > dsound - > ds3dl . vOrientTop . u3 . z = zTop ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition (
LPDIRECTSOUND3DLISTENER iface ,
D3DVALUE x , D3DVALUE y , D3DVALUE z ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: Position vector = (%f,%f,%f); dwApply = %ld \n " , x , y , z , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl . vPosition . u1 . x = x ;
This - > dsound - > ds3dl . vPosition . u2 . y = y ;
This - > dsound - > ds3dl . vPosition . u3 . z = z ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor (
LPDIRECTSOUND3DLISTENER iface ,
D3DVALUE fRolloffFactor ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: Rolloff Factor = %f; dwApply = %ld \n " , fRolloffFactor , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl . flRolloffFactor = fRolloffFactor ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity (
LPDIRECTSOUND3DLISTENER iface ,
D3DVALUE x , D3DVALUE y , D3DVALUE z ,
DWORD dwApply )
{
2002-12-14 00:20:58 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " setting: Velocity vector = (%f,%f,%f); dwApply = %ld \n " , x , y , z , dwApply ) ;
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl . vVelocity . u1 . x = x ;
This - > dsound - > ds3dl . vVelocity . u2 . y = y ;
This - > dsound - > ds3dl . vVelocity . u3 . z = z ;
2002-12-14 00:20:58 +01:00
if ( dwApply = = DS3D_IMMEDIATE )
{
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = FALSE ;
2003-01-04 02:22:51 +01:00
DSOUND_ChangeListener ( This ) ;
2002-12-14 00:20:58 +01:00
}
2003-06-28 00:22:15 +02:00
This - > dsound - > ds3dl_need_recalc = TRUE ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings (
LPDIRECTSOUND3DLISTENER iface )
{
2003-01-04 02:22:51 +01:00
ICOM_THIS ( IDirectSound3DListenerImpl , iface ) ;
TRACE ( " \n " ) ;
DSOUND_ChangeListener ( This ) ;
2002-06-13 21:15:06 +02:00
return DS_OK ;
}
static ICOM_VTABLE ( IDirectSound3DListener ) ds3dlvt =
{
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
/* IUnknown methods */
IDirectSound3DListenerImpl_QueryInterface ,
IDirectSound3DListenerImpl_AddRef ,
IDirectSound3DListenerImpl_Release ,
/* IDirectSound3DListener methods */
IDirectSound3DListenerImpl_GetAllParameter ,
IDirectSound3DListenerImpl_GetDistanceFactor ,
IDirectSound3DListenerImpl_GetDopplerFactor ,
IDirectSound3DListenerImpl_GetOrientation ,
IDirectSound3DListenerImpl_GetPosition ,
IDirectSound3DListenerImpl_GetRolloffFactor ,
IDirectSound3DListenerImpl_GetVelocity ,
IDirectSound3DListenerImpl_SetAllParameters ,
IDirectSound3DListenerImpl_SetDistanceFactor ,
IDirectSound3DListenerImpl_SetDopplerFactor ,
IDirectSound3DListenerImpl_SetOrientation ,
IDirectSound3DListenerImpl_SetPosition ,
IDirectSound3DListenerImpl_SetRolloffFactor ,
IDirectSound3DListenerImpl_SetVelocity ,
IDirectSound3DListenerImpl_CommitDeferredSettings ,
} ;
HRESULT WINAPI IDirectSound3DListenerImpl_Create (
PrimaryBufferImpl * This ,
IDirectSound3DListenerImpl * * pdsl )
{
IDirectSound3DListenerImpl * dsl ;
2003-05-22 05:39:13 +02:00
TRACE ( " (%p,%p) \n " , This , pdsl ) ;
dsl = ( IDirectSound3DListenerImpl * ) HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , sizeof ( * dsl ) ) ;
if ( dsl = = NULL ) {
WARN ( " out of memory \n " ) ;
2003-06-28 00:22:15 +02:00
* pdsl = 0 ;
2003-05-22 05:39:13 +02:00
return DSERR_OUTOFMEMORY ;
}
2002-06-13 21:15:06 +02:00
2003-06-28 00:22:15 +02:00
dsl - > ref = 0 ;
2003-04-10 20:17:34 +02:00
dsl - > lpVtbl = & ds3dlvt ;
2002-06-13 21:15:06 +02:00
2003-06-28 00:22:15 +02:00
dsl - > dsound = This - > dsound ;
dsl - > dsound - > ds3dl . dwSize = sizeof ( DS3DLISTENER ) ;
dsl - > dsound - > ds3dl . vPosition . u1 . x = 0.0 ;
dsl - > dsound - > ds3dl . vPosition . u2 . y = 0.0 ;
dsl - > dsound - > ds3dl . vPosition . u3 . z = 0.0 ;
dsl - > dsound - > ds3dl . vVelocity . u1 . x = 0.0 ;
dsl - > dsound - > ds3dl . vVelocity . u2 . y = 0.0 ;
dsl - > dsound - > ds3dl . vVelocity . u3 . z = 0.0 ;
dsl - > dsound - > ds3dl . vOrientFront . u1 . x = 0.0 ;
dsl - > dsound - > ds3dl . vOrientFront . u2 . y = 0.0 ;
dsl - > dsound - > ds3dl . vOrientFront . u3 . z = 1.0 ;
dsl - > dsound - > ds3dl . vOrientTop . u1 . x = 0.0 ;
dsl - > dsound - > ds3dl . vOrientTop . u2 . y = 1.0 ;
dsl - > dsound - > ds3dl . vOrientTop . u3 . z = 0.0 ;
dsl - > dsound - > ds3dl . flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR ;
dsl - > dsound - > ds3dl . flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR ;
dsl - > dsound - > ds3dl . flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR ;
dsl - > dsound - > ds3dl_need_recalc = TRUE ;
InitializeCriticalSection ( & dsl - > dsound - > ds3dl_lock ) ;
IDirectSound8_AddRef ( ( LPDIRECTSOUND8 ) This - > dsound ) ;
2002-06-13 21:15:06 +02:00
* pdsl = dsl ;
return S_OK ;
}