dsound DirectSound/DirectSound8 patch
Robert Reif
reif at earthlink.net
Wed Jun 30 20:19:14 CDT 2004
Wine currently defines DirectSoundCreate and DirectSoundCreate8
as the same function and only supplies a DirectSound8 implementation.
They are two separate functions and interfaces in windows.
This patch separates DirectSoundCreate8 into two functions and
adds a IDirectSound implementation. Adds proper COM behavior
for QueryInterface for IDirectSound and IDirectSound8. The
DirectSound code is moved from dsound_main.c to a new file
dsound.c.
Fixes a bug in the dsound.h header file for IDirectSound8
CreateSoundBuffer and DuplicateSoundBuffer.
Adds new tests for proper COM behavior and enables some
commented out code for tests that work on windows . Adds
new tests for IDirectSound8.
To Do:
Do the same thing for DirectSoundCapture and DirectSoundBuffer.
Fix DirectSound to Release properly even when buffers are active.
-------------- next part --------------
Index: dlls/dsound/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/dsound/Makefile.in,v
retrieving revision 1.20
diff -u -r1.20 Makefile.in
--- dlls/dsound/Makefile.in 27 Jan 2004 00:11:17 -0000 1.20
+++ dlls/dsound/Makefile.in 1 Jul 2004 00:20:18 -0000
@@ -9,6 +9,7 @@
C_SRCS = \
buffer.c \
capture.c \
+ dsound.c \
dsound_main.c \
mixer.c \
primary.c \
Index: dlls/dsound/dsound.spec
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound.spec,v
retrieving revision 1.16
diff -u -r1.16 dsound.spec
--- dlls/dsound/dsound.spec 1 Oct 2003 03:05:25 -0000 1.16
+++ dlls/dsound/dsound.spec 1 Jul 2004 00:20:18 -0000
@@ -1,4 +1,4 @@
-1 stdcall DirectSoundCreate(ptr ptr ptr) DirectSoundCreate8
+1 stdcall DirectSoundCreate(ptr ptr ptr)
2 stdcall DirectSoundEnumerateA(ptr ptr)
3 stdcall DirectSoundEnumerateW(ptr ptr)
4 stdcall -private DllCanUnloadNow() DSOUND_DllCanUnloadNow
Index: dlls/dsound/dsound_main.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_main.c,v
retrieving revision 1.99
diff -u -r1.99 dsound_main.c
--- dlls/dsound/dsound_main.c 19 May 2004 03:22:56 -0000 1.99
+++ dlls/dsound/dsound_main.c 1 Jul 2004 00:20:18 -0000
@@ -438,773 +438,6 @@
return DS_OK;
}
-
-static void _dump_DSBCAPS(DWORD xmask) {
- struct {
- DWORD mask;
- char *name;
- } flags[] = {
-#define FE(x) { x, #x },
- FE(DSBCAPS_PRIMARYBUFFER)
- FE(DSBCAPS_STATIC)
- FE(DSBCAPS_LOCHARDWARE)
- FE(DSBCAPS_LOCSOFTWARE)
- FE(DSBCAPS_CTRL3D)
- FE(DSBCAPS_CTRLFREQUENCY)
- FE(DSBCAPS_CTRLPAN)
- FE(DSBCAPS_CTRLVOLUME)
- FE(DSBCAPS_CTRLPOSITIONNOTIFY)
- FE(DSBCAPS_CTRLDEFAULT)
- FE(DSBCAPS_CTRLALL)
- FE(DSBCAPS_STICKYFOCUS)
- FE(DSBCAPS_GLOBALFOCUS)
- FE(DSBCAPS_GETCURRENTPOSITION2)
- FE(DSBCAPS_MUTE3DATMAXDISTANCE)
-#undef FE
- };
- int i;
-
- for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
- if ((flags[i].mask & xmask) == flags[i].mask)
- DPRINTF("%s ",flags[i].name);
-}
-
-/*******************************************************************************
- * IDirectSound
- */
-
-static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
- LPDIRECTSOUND8 iface,HWND hwnd,DWORD level
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,%08lx,%ld(%s))\n",This,(DWORD)hwnd,level,
- level == DSSCL_NORMAL ? "DSSCL_NORMAL" :
- level == DSSCL_PRIORITY ? "DSSCL_PRIORITY" :
- level == DSSCL_EXCLUSIVE ? "DSSCL_EXCLUSIVE" :
- level == DSSCL_WRITEPRIMARY ? "DSSCL_WRITEPRIMARY" : "Unknown");
-
- if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
- FIXME("level=%s not fully supported\n",
- level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
- }
-
- This->priolevel = level;
-
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
- LPDIRECTSOUND8 iface,LPCDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER8 ppdsb,LPUNKNOWN lpunk
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- LPWAVEFORMATEX wfex;
- HRESULT hres = DS_OK;
-
- TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (dsbd == NULL) {
- WARN("invalid parameter: dsbd == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (dsbd->dwSize != sizeof(DSBUFFERDESC) && dsbd->dwSize != sizeof(DSBUFFERDESC1)) {
- WARN("invalid parameter: dsbd\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (TRACE_ON(dsound)) {
- TRACE("(structsize=%ld)\n",dsbd->dwSize);
- TRACE("(flags=0x%08lx:\n",dsbd->dwFlags);
- _dump_DSBCAPS(dsbd->dwFlags);
- DPRINTF(")\n");
- TRACE("(bufferbytes=%ld)\n",dsbd->dwBufferBytes);
- TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
- }
-
- wfex = dsbd->lpwfxFormat;
-
- if (wfex)
- TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
- "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
- wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
- wfex->nAvgBytesPerSec, wfex->nBlockAlign,
- wfex->wBitsPerSample, wfex->cbSize);
-
- if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
- if (This->primary) {
- WARN("Primary Buffer already created\n");
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
- } else {
- This->dsbd = *dsbd;
- hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
- if (This->primary) {
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
- *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
- } else
- WARN("PrimaryBufferImpl_Create failed\n");
- }
- } else {
- IDirectSoundBufferImpl * dsb;
- hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
- if (dsb) {
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
- } else
- WARN("SecondaryBufferImpl_Create failed\n");
- } else
- WARN("IDirectSoundBufferImpl_Create failed\n");
- }
-
- return hres;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
- LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 psb,LPLPDIRECTSOUNDBUFFER8 ppdsb
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- IDirectSoundBufferImpl* pdsb;
- IDirectSoundBufferImpl* dsb;
- HRESULT hres = DS_OK;
- TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (psb == NULL) {
- WARN("invalid parameter: psb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (ppdsb == NULL) {
- WARN("invalid parameter: ppdsb == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* FIXME: hack to make sure we have a secondary buffer */
- if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
- ERR("trying to duplicate primary buffer\n");
- *ppdsb = NULL;
- return DSERR_INVALIDCALL;
- }
-
- pdsb = ((SecondaryBufferImpl *)psb)->dsb;
-
- dsb = (IDirectSoundBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
-
- if (dsb == NULL) {
- WARN("out of memory\n");
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
-
- if (pdsb->hwbuf) {
- TRACE("duplicating hardware buffer\n");
-
- hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
- if (hres != DS_OK) {
- TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
- dsb->hwbuf = NULL;
- /* allocate buffer */
- if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
- dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
- if (dsb->buffer == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
-
- dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
- if (dsb->buffer->memory == NULL) {
- WARN("out of memory\n");
- HeapFree(GetProcessHeap(),0,dsb->buffer);
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = NULL;
- return DSERR_OUTOFMEMORY;
- }
- dsb->buffer->ref = 1;
-
- /* FIXME: copy buffer ? */
- }
- }
- } else {
- dsb->hwbuf = NULL;
- dsb->buffer->ref++;
- }
-
- dsb->ref = 0;
- dsb->state = STATE_STOPPED;
- dsb->playpos = 0;
- dsb->buf_mixpos = 0;
- dsb->dsound = This;
- dsb->ds3db = NULL;
- dsb->iks = NULL; /* FIXME? */
- dsb->dsb = NULL;
- memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
- InitializeCriticalSection(&(dsb->lock));
- /* register buffer */
- RtlAcquireResourceExclusive(&(This->lock), TRUE);
- {
- IDirectSoundBufferImpl **newbuffers;
- if (This->buffers)
- newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
- else
- newbuffers = (IDirectSoundBufferImpl**)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
-
- if (newbuffers) {
- This->buffers = newbuffers;
- This->buffers[This->nrofbuffers] = dsb;
- This->nrofbuffers++;
- TRACE("buffer count is now %d\n", This->nrofbuffers);
- } else {
- ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers);
- IDirectSoundBuffer8_Release(psb);
- DeleteCriticalSection(&(dsb->lock));
- RtlReleaseResource(&(This->lock));
- HeapFree(GetProcessHeap(),0,dsb);
- *ppdsb = 0;
- return DSERR_OUTOFMEMORY;
- }
- }
- RtlReleaseResource(&(This->lock));
- IDirectSound_AddRef(iface);
- hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
- if (*ppdsb) {
- dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
- IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
- } else
- WARN("SecondaryBufferImpl_Create failed\n");
-
- return hres;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS lpDSCaps) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,%p)\n",This,lpDSCaps);
-
- if (This == NULL) {
- WARN("invalid parameter: This == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- if (lpDSCaps == NULL) {
- WARN("invalid parameter: lpDSCaps = NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* check is there is enough room */
- if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
- WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
- lpDSCaps->dwSize, sizeof(*lpDSCaps));
- return DSERR_INVALIDPARAM;
- }
-
- lpDSCaps->dwFlags = This->drvcaps.dwFlags;
- TRACE("(flags=0x%08lx)\n",lpDSCaps->dwFlags);
-
- lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
- lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
-
- lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
-
- lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
- lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
- lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
-
- lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
- lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
- lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
-
- lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
- lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
- lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
-
- lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
- lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
- lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
-
- lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
-
- lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
-
- lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
-
- /* driver doesn't have these */
- lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
-
- lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
-
- return DS_OK;
-}
-
-static ULONG WINAPI IDirectSoundImpl_AddRef(LPDIRECTSOUND8 iface) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- return InterlockedIncrement(&This->ref);
-}
-
-static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) {
- ICOM_THIS(IDirectSoundImpl,iface);
- ULONG ulReturn;
-
- TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
- ulReturn = InterlockedDecrement(&This->ref);
- if (ulReturn == 0) {
- HRESULT hres;
- UINT i;
-
- timeKillEvent(This->timerID);
- timeEndPeriod(DS_TIME_RES);
- /* wait for timer to expire */
- Sleep(DS_TIME_RES+1);
-
- RtlAcquireResourceShared(&(This->lock), TRUE);
-
- if (This->buffers) {
- for( i=0;i<This->nrofbuffers;i++)
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
- }
-
- RtlReleaseResource(&(This->lock));
-
- if (This->primary) {
- WARN("primary buffer not released\n");
- IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
- }
-
- hres = DSOUND_PrimaryDestroy(This);
- if (hres != DS_OK)
- WARN("DSOUND_PrimaryDestroy failed\n");
-
- if (This->driver)
- IDsDriver_Close(This->driver);
-
- if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- waveOutClose(This->hwo);
-
- if (This->driver)
- IDsDriver_Release(This->driver);
-
- RtlDeleteResource(&This->lock);
- DeleteCriticalSection(&This->mixlock);
- HeapFree(GetProcessHeap(),0,This);
- dsound = NULL;
- TRACE("(%p) released\n",This);
- }
-
- return ulReturn;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
- LPDIRECTSOUND8 iface,DWORD config
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,0x%08lx)\n",This,config);
-
- This->speaker_config = config;
-
- WARN("not fully functional\n");
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
- LPDIRECTSOUND8 iface,REFIID riid,LPVOID *ppobj
-) {
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
-
- if (ppobj == NULL) {
- WARN("invalid parameter\n");
- return E_INVALIDARG;
- }
-
- *ppobj = NULL; /* assume failure */
-
- if ( IsEqualGUID(riid, &IID_IUnknown) ||
- IsEqualGUID(riid, &IID_IDirectSound) ||
- IsEqualGUID(riid, &IID_IDirectSound8) ) {
- IDirectSound8_AddRef((LPDIRECTSOUND8)This);
- *ppobj = This;
- return S_OK;
- }
-
- if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
- WARN("app requested IDirectSound3DListener on dsound object\n");
- return E_NOINTERFACE;
- }
-
- FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
- return E_NOINTERFACE;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_Compact(
- LPDIRECTSOUND8 iface)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p)\n", This);
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
- LPDIRECTSOUND8 iface,
- LPDWORD lpdwSpeakerConfig)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
-
- if (lpdwSpeakerConfig == NULL) {
- WARN("invalid parameter\n");
- return DSERR_INVALIDPARAM;
- }
-
- WARN("not fully functional\n");
-
- *lpdwSpeakerConfig = This->speaker_config;
-
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_Initialize(
- LPDIRECTSOUND8 iface,
- LPCGUID lpcGuid)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
- return DS_OK;
-}
-
-static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
- LPDIRECTSOUND8 iface,
- LPDWORD pdwCertified)
-{
- ICOM_THIS(IDirectSoundImpl,iface);
- TRACE("(%p, %p)\n", This, pdwCertified);
- *pdwCertified = DS_CERTIFIED;
- return DS_OK;
-}
-
-static ICOM_VTABLE(IDirectSound8) dsvt =
-{
- ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
- IDirectSoundImpl_QueryInterface,
- IDirectSoundImpl_AddRef,
- IDirectSoundImpl_Release,
- IDirectSoundImpl_CreateSoundBuffer,
- IDirectSoundImpl_GetCaps,
- IDirectSoundImpl_DuplicateSoundBuffer,
- IDirectSoundImpl_SetCooperativeLevel,
- IDirectSoundImpl_Compact,
- IDirectSoundImpl_GetSpeakerConfig,
- IDirectSoundImpl_SetSpeakerConfig,
- IDirectSoundImpl_Initialize,
- IDirectSoundImpl_VerifyCertification
-};
-
-
-/*******************************************************************************
- * DirectSoundCreate (DSOUND.1)
- *
- * Creates and initializes a DirectSound interface.
- *
- * PARAMS
- * lpcGUID [I] Address of the GUID that identifies the sound device.
- * ppDS [O] Address of a variable to receive the interface pointer.
- * pUnkOuter [I] Must be NULL.
- *
- * RETURNS
- * Success: DS_OK
- * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
- * DSERR_NODRIVER, DSERR_OUTOFMEMORY
- */
-HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
-{
- IDirectSoundImpl** ippDS=(IDirectSoundImpl**)ppDS;
- PIDSDRIVER drv = NULL;
- unsigned wod, wodn;
- HRESULT err = DSERR_INVALIDPARAM;
- GUID devGuid;
- BOOLEAN found = FALSE;
-
- TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ippDS,pUnkOuter);
-
- if (ippDS == NULL) {
- WARN("invalid parameter: ippDS == NULL\n");
- return DSERR_INVALIDPARAM;
- }
-
- /* Get dsound configuration */
- setup_dsound_options();
-
- /* Default device? */
- if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
- lpcGUID = &DSDEVID_DefaultPlayback;
-
- if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
- WARN("invalid parameter: lpcGUID\n");
- *ippDS = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (dsound) {
- if (IsEqualGUID(&devGuid, &dsound->guid) ) {
- /* FIXME: this is wrong, need to create a new instance */
- ERR("dsound already opened\n");
- IDirectSound_AddRef((LPDIRECTSOUND)dsound);
- *ippDS = dsound;
- return DS_OK;
- } else {
- ERR("different dsound already opened\n");
- }
- }
-
- /* Enumerate WINMM audio devices and find the one we want */
- wodn = waveOutGetNumDevs();
- if (!wodn) {
- WARN("no driver\n");
- *ippDS = NULL;
- return DSERR_NODRIVER;
- }
-
- TRACE(" expecting GUID %s.\n", debugstr_guid(&devGuid));
-
- for (wod=0; wod<wodn; wod++) {
- GUID guid;
- err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
- if (err != DS_OK) {
- WARN("waveOutMessage failed; err=%lx\n",err);
- *ippDS = NULL;
- return err;
- }
- TRACE("got GUID %s for wod %d.\n", debugstr_guid(&guid), wod);
- if (IsEqualGUID( &devGuid, &guid) ) {
- err = DS_OK;
- found = TRUE;
- break;
- }
- }
-
- if (err != DS_OK) {
- WARN("invalid parameter\n");
- *ippDS = NULL;
- return DSERR_INVALIDPARAM;
- }
-
- if (found == FALSE) {
- WARN("No device found matching given ID - trying with default one !\n");
- wod = ds_default_playback;
- }
-
- /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
- waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
-
- /* Disable the direct sound driver to force emulation if requested. */
- if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
- drv = NULL;
-
- /* Allocate memory */
- *ippDS = (IDirectSoundImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
- if (*ippDS == NULL) {
- WARN("out of memory\n");
- return DSERR_OUTOFMEMORY;
- }
-
- (*ippDS)->lpVtbl = &dsvt;
- (*ippDS)->ref = 1;
-
- (*ippDS)->driver = drv;
- (*ippDS)->priolevel = DSSCL_NORMAL;
- (*ippDS)->fraglen = 0;
- (*ippDS)->hwbuf = NULL;
- (*ippDS)->buffer = NULL;
- (*ippDS)->buflen = 0;
- (*ippDS)->writelead = 0;
- (*ippDS)->state = STATE_STOPPED;
- (*ippDS)->nrofbuffers = 0;
- (*ippDS)->buffers = NULL;
- (*ippDS)->primary = NULL;
- (*ippDS)->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
-
- /* 3D listener initial parameters */
- (*ippDS)->listener = NULL;
- (*ippDS)->ds3dl.dwSize = sizeof(DS3DLISTENER);
- (*ippDS)->ds3dl.vPosition.x = 0.0;
- (*ippDS)->ds3dl.vPosition.y = 0.0;
- (*ippDS)->ds3dl.vPosition.z = 0.0;
- (*ippDS)->ds3dl.vVelocity.x = 0.0;
- (*ippDS)->ds3dl.vVelocity.y = 0.0;
- (*ippDS)->ds3dl.vVelocity.z = 0.0;
- (*ippDS)->ds3dl.vOrientFront.x = 0.0;
- (*ippDS)->ds3dl.vOrientFront.y = 0.0;
- (*ippDS)->ds3dl.vOrientFront.z = 1.0;
- (*ippDS)->ds3dl.vOrientTop.x = 0.0;
- (*ippDS)->ds3dl.vOrientTop.y = 1.0;
- (*ippDS)->ds3dl.vOrientTop.z = 0.0;
- (*ippDS)->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
- (*ippDS)->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
- (*ippDS)->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
-
- (*ippDS)->prebuf = ds_snd_queue_max;
- (*ippDS)->guid = devGuid;
-
- /* Get driver description */
- if (drv) {
- err = IDsDriver_GetDriverDesc(drv,&((*ippDS)->drvdesc));
- if (err != DS_OK) {
- WARN("IDsDriver_GetDriverDesc failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- } else {
- /* if no DirectSound interface available, use WINMM API instead */
- (*ippDS)->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
- }
-
- (*ippDS)->drvdesc.dnDevNode = wod;
-
- /* Set default wave format (may need it for waveOutOpen) */
- (*ippDS)->wfx.wFormatTag = WAVE_FORMAT_PCM;
- /* We rely on the sound driver to return the actual sound format of
- * the device if it does not support 22050x8x2 and is given the
- * WAVE_DIRECTSOUND flag.
- */
- (*ippDS)->wfx.nSamplesPerSec = 22050;
- (*ippDS)->wfx.wBitsPerSample = 8;
- (*ippDS)->wfx.nChannels = 2;
- (*ippDS)->wfx.nBlockAlign = (*ippDS)->wfx.wBitsPerSample * (*ippDS)->wfx.nChannels / 8;
- (*ippDS)->wfx.nAvgBytesPerSec = (*ippDS)->wfx.nSamplesPerSec * (*ippDS)->wfx.nBlockAlign;
- (*ippDS)->wfx.cbSize = 0;
-
- /* If the driver requests being opened through MMSYSTEM
- * (which is recommended by the DDK), it is supposed to happen
- * before the DirectSound interface is opened */
- if ((*ippDS)->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
- {
- DWORD flags = CALLBACK_FUNCTION;
-
- /* disable direct sound if requested */
- if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
- flags |= WAVE_DIRECTSOUND;
-
- err = mmErr(waveOutOpen(&((*ippDS)->hwo),
- (*ippDS)->drvdesc.dnDevNode, &((*ippDS)->wfx),
- (DWORD)DSOUND_callback, (DWORD)(*ippDS),
- flags));
- if (err != DS_OK) {
- WARN("waveOutOpen failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- }
-
- if (drv) {
- err = IDsDriver_Open(drv);
- if (err != DS_OK) {
- WARN("IDsDriver_Open failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
-
- /* the driver is now open, so it's now allowed to call GetCaps */
- err = IDsDriver_GetCaps(drv,&((*ippDS)->drvcaps));
- if (err != DS_OK) {
- WARN("IDsDriver_GetCaps failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- } else {
- WAVEOUTCAPSA woc;
- err = mmErr(waveOutGetDevCapsA((*ippDS)->drvdesc.dnDevNode, &woc, sizeof(woc)));
- if (err != DS_OK) {
- WARN("waveOutGetDevCaps failed\n");
- HeapFree(GetProcessHeap(),0,*ippDS);
- *ippDS = NULL;
- return err;
- }
- ZeroMemory(&(*ippDS)->drvcaps, sizeof((*ippDS)->drvcaps));
- if ((woc.dwFormats & WAVE_FORMAT_1M08) ||
- (woc.dwFormats & WAVE_FORMAT_2M08) ||
- (woc.dwFormats & WAVE_FORMAT_4M08) ||
- (woc.dwFormats & WAVE_FORMAT_48M08) ||
- (woc.dwFormats & WAVE_FORMAT_96M08)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
- }
- if ((woc.dwFormats & WAVE_FORMAT_1M16) ||
- (woc.dwFormats & WAVE_FORMAT_2M16) ||
- (woc.dwFormats & WAVE_FORMAT_4M16) ||
- (woc.dwFormats & WAVE_FORMAT_48M16) ||
- (woc.dwFormats & WAVE_FORMAT_96M16)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
- }
- if ((woc.dwFormats & WAVE_FORMAT_1S08) ||
- (woc.dwFormats & WAVE_FORMAT_2S08) ||
- (woc.dwFormats & WAVE_FORMAT_4S08) ||
- (woc.dwFormats & WAVE_FORMAT_48S08) ||
- (woc.dwFormats & WAVE_FORMAT_96S08)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
- }
- if ((woc.dwFormats & WAVE_FORMAT_1S16) ||
- (woc.dwFormats & WAVE_FORMAT_2S16) ||
- (woc.dwFormats & WAVE_FORMAT_4S16) ||
- (woc.dwFormats & WAVE_FORMAT_48S16) ||
- (woc.dwFormats & WAVE_FORMAT_96S16)) {
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
- }
- if (ds_emuldriver)
- (*ippDS)->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
- (*ippDS)->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
- (*ippDS)->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
- (*ippDS)->drvcaps.dwPrimaryBuffers = 1;
- }
-
- (*ippDS)->volpan.lVolume = 0;
- (*ippDS)->volpan.lPan = 0;
- DSOUND_RecalcVolPan(&((*ippDS)->volpan));
-
- InitializeCriticalSection(&((*ippDS)->mixlock));
- RtlInitializeResource(&((*ippDS)->lock));
-
- if (!dsound) {
- HRESULT hres;
- dsound = (*ippDS);
- hres = DSOUND_PrimaryCreate(dsound);
- if (hres != DS_OK) {
- WARN("DSOUND_PrimaryCreate failed\n");
- return hres;
- }
- timeBeginPeriod(DS_TIME_RES);
- dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
- (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
- }
-
- return DS_OK;
-}
-
-
/*******************************************************************************
* DirectSound ClassFactory
*/
Index: dlls/dsound/dsound_private.h
===================================================================
RCS file: /home/wine/wine/dlls/dsound/dsound_private.h,v
retrieving revision 1.15
diff -u -r1.15 dsound_private.h
--- dlls/dsound/dsound_private.h 17 Mar 2004 01:44:15 -0000 1.15
+++ dlls/dsound/dsound_private.h 1 Jul 2004 00:20:18 -0000
@@ -44,20 +44,25 @@
/*****************************************************************************
* Predeclare the interface implementation structures
*/
-typedef struct IDirectSoundImpl IDirectSoundImpl;
-typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
-typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
+typedef struct IDirectSoundImpl IDirectSoundImpl;
+typedef struct IDirectSound_IUnknown IDirectSound_IUnknown;
+typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound;
+typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown;
+typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound;
+typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8;
+typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
+typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
-typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
-typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
+typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
+typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
-typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
-typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
-typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
-typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
-typedef struct PrimaryBufferImpl PrimaryBufferImpl;
-typedef struct SecondaryBufferImpl SecondaryBufferImpl;
-typedef struct IClassFactoryImpl IClassFactoryImpl;
+typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
+typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
+typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
+typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
+typedef struct PrimaryBufferImpl PrimaryBufferImpl;
+typedef struct SecondaryBufferImpl SecondaryBufferImpl;
+typedef struct IClassFactoryImpl IClassFactoryImpl;
/*****************************************************************************
* IDirectSound implementation structure
@@ -95,6 +100,10 @@
IDirectSound3DListenerImpl* listener;
DS3DLISTENER ds3dl;
BOOL ds3dl_need_recalc;
+
+ LPUNKNOWN pUnknown;
+ LPDIRECTSOUND pDS;
+ LPDIRECTSOUND8 pDS8;
};
/* reference counted buffer memory for duplicated buffer memory */
@@ -103,6 +112,66 @@
DWORD ref;
LPBYTE memory;
} BufferMemory;
+
+HRESULT WINAPI IDirectSoundImpl_Create(
+ LPCGUID lpcGUID,
+ LPDIRECTSOUND8 * ppds);
+
+/*****************************************************************************
+ * IDirectSound COM components
+ */
+struct IDirectSound_IUnknown {
+ ICOM_VFIELD(IUnknown);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk);
+
+struct IDirectSound_IDirectSound {
+ ICOM_VFIELD(IDirectSound);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds);
+
+/*****************************************************************************
+ * IDirectSound8 COM components
+ */
+struct IDirectSound8_IUnknown {
+ ICOM_VFIELD(IUnknown);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound8_IUnknown_Create(
+ LPDIRECTSOUND8 pds,
+ LPUNKNOWN * ppunk);
+
+struct IDirectSound8_IDirectSound {
+ ICOM_VFIELD(IDirectSound);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound8_IDirectSound_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND * ppds);
+
+struct IDirectSound8_IDirectSound8 {
+ ICOM_VFIELD(IDirectSound8);
+ DWORD ref;
+ LPDIRECTSOUND8 pds;
+};
+
+HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
+ LPDIRECTSOUND8 pds,
+ LPDIRECTSOUND8 * ppds);
/*****************************************************************************
* IDirectSoundBuffer implementation structure
Index: dlls/dsound/tests/dsound.c
===================================================================
RCS file: /home/wine/wine/dlls/dsound/tests/dsound.c,v
retrieving revision 1.21
diff -u -r1.21 dsound.c
--- dlls/dsound/tests/dsound.c 17 Jun 2004 23:03:11 -0000 1.21
+++ dlls/dsound/tests/dsound.c 1 Jul 2004 00:20:19 -0000
@@ -36,6 +36,7 @@
#include "windef.h"
#include "wingdi.h"
#include "dsound.h"
+#include "dxerr9.h"
#include "dsound_test.h"
@@ -46,32 +47,51 @@
LPDIRECTSOUND dso=NULL;
DSCAPS dscaps;
int ref;
+ IUnknown * unknown;
+ IDirectSound * ds;
+ IDirectSound8 * ds8;
/* DSOUND: Error: Invalid interface buffer */
rc=DirectSoundCreate(lpGuid,0,NULL);
- ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: 0x%lx\n",rc);
+ ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate should have failed: %s\n",DXGetErrorString9(rc));
/* Create the DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc!=DS_OK)
return rc;
+ /* Try to Query for objects */
+ rc=IDirectSound_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
+ ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound_Release(unknown);
+
+ rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
+ ok(rc==DS_OK,"IDirectSound_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound_Release(ds);
+
+ rc=IDirectSound_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
+ ok(rc==E_NOINTERFACE,"IDirectSound_QueryInterface(IID_IDirectSound8) should have failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound8_Release(ds8);
+
/* DSOUND: Error: Invalid caps buffer */
rc=IDirectSound_GetCaps(dso,0);
- ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
ZeroMemory(&dscaps, sizeof(dscaps));
/* DSOUND: Error: Invalid caps buffer */
rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: 0x%lx\n",rc);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
dscaps.dwSize=sizeof(dscaps);
/* DSOUND: Running on a certified driver */
rc=IDirectSound_GetCaps(dso,&dscaps);
- ok(rc==DS_OK,"GetCaps failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
trace(" DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
@@ -84,17 +104,15 @@
if (ref!=0)
return DSERR_GENERIC;
-#if 0
- /* FIXME: this works on windows */
/* Create a DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso,NULL);
- ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
LPDIRECTSOUND dso1=NULL;
/* Create a second DirectSound object */
rc=DirectSoundCreate(lpGuid,&dso1,NULL);
- ok(rc==DS_OK,"DirectSoundCreate failed: 0x%lx\n",rc);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
if (rc==DS_OK) {
/* Release the second DirectSound object */
ref=IDirectSound_Release(dso1);
@@ -109,7 +127,96 @@
return DSERR_GENERIC;
} else
return rc;
-#endif
+
+ return DS_OK;
+}
+
+static HRESULT test_dsound8(LPGUID lpGuid)
+{
+ HRESULT rc;
+ LPDIRECTSOUND8 dso=NULL;
+ DSCAPS dscaps;
+ int ref;
+ IUnknown * unknown;
+ IDirectSound * ds;
+ IDirectSound8 * ds8;
+
+ /* DSOUND: Error: Invalid interface buffer */
+ rc=DirectSoundCreate8(lpGuid,0,NULL);
+ ok(rc==DSERR_INVALIDPARAM,"DirectSoundCreate8 should have failed: %s\n",DXGetErrorString9(rc));
+
+ /* Create the DirectSound8 object */
+ rc=DirectSoundCreate8(lpGuid,&dso,NULL);
+ ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
+ if (rc!=DS_OK)
+ return rc;
+
+ /* Try to Query for objects */
+ rc=IDirectSound8_QueryInterface(dso,&IID_IUnknown,(LPVOID*)&unknown);
+ ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IUnknown) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound8_Release(unknown);
+
+ rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound,(LPVOID*)&ds);
+ ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound_Release(ds);
+
+ rc=IDirectSound8_QueryInterface(dso,&IID_IDirectSound8,(LPVOID*)&ds8);
+ ok(rc==DS_OK,"IDirectSound8_QueryInterface(IID_IDirectSound8) failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK)
+ IDirectSound8_Release(ds8);
+
+ /* DSOUND: Error: Invalid caps buffer */
+ rc=IDirectSound8_GetCaps(dso,0);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
+
+ ZeroMemory(&dscaps, sizeof(dscaps));
+
+ /* DSOUND: Error: Invalid caps buffer */
+ rc=IDirectSound8_GetCaps(dso,&dscaps);
+ ok(rc==DSERR_INVALIDPARAM,"GetCaps should have failed: %s\n",DXGetErrorString9(rc));
+
+ dscaps.dwSize=sizeof(dscaps);
+
+ /* DSOUND: Running on a certified driver */
+ rc=IDirectSound8_GetCaps(dso,&dscaps);
+ ok(rc==DS_OK,"GetCaps failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK) {
+ trace(" DirectSound Caps: flags=0x%08lx secondary min=%ld max=%ld\n",
+ dscaps.dwFlags,dscaps.dwMinSecondarySampleRate,
+ dscaps.dwMaxSecondarySampleRate);
+ }
+
+ /* Release the DirectSound8 object */
+ ref=IDirectSound8_Release(dso);
+ ok(ref==0,"IDirectSound_Release has %d references, should have 0\n",ref);
+ if (ref!=0)
+ return DSERR_GENERIC;
+
+ /* Create a DirectSound8 object */
+ rc=DirectSoundCreate8(lpGuid,&dso,NULL);
+ ok(rc==DS_OK,"DirectSoundCreate failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK) {
+ LPDIRECTSOUND8 dso1=NULL;
+
+ /* Create a second DirectSound8 object */
+ rc=DirectSoundCreate8(lpGuid,&dso1,NULL);
+ ok(rc==DS_OK,"DirectSoundCreate8 failed: %s\n",DXGetErrorString9(rc));
+ if (rc==DS_OK) {
+ /* Release the second DirectSound8 object */
+ ref=IDirectSound8_Release(dso1);
+ ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
+ ok(dso!=dso1,"DirectSound8 objects should be unique: dso=0x%08lx,dso1=0x%08lx\n",(DWORD)dso,(DWORD)dso1);
+ }
+
+ /* Release the first DirectSound8 object */
+ ref=IDirectSound8_Release(dso);
+ ok(ref==0,"IDirectSound8_Release has %d references, should have 0\n",ref);
+ if (ref!=0)
+ return DSERR_GENERIC;
+ } else
+ return rc;
return DS_OK;
}
@@ -294,6 +401,7 @@
{
trace("*** Testing %s - %s\n",lpcstrDescription,lpcstrModule);
test_dsound(lpGuid);
+ test_dsound8(lpGuid);
test_primary(lpGuid);
test_secondary(lpGuid);
Index: include/dsound.h
===================================================================
RCS file: /home/wine/wine/include/dsound.h,v
retrieving revision 1.44
diff -u -r1.44 dsound.h
--- include/dsound.h 19 Apr 2004 02:58:45 -0000 1.44
+++ include/dsound.h 1 Jul 2004 00:20:33 -0000
@@ -456,9 +456,9 @@
#define INTERFACE IDirectSound8
#define IDirectSound8_METHODS \
IUnknown_METHODS \
- STDMETHOD(CreateSoundBuffer)(THIS_ LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER8 lplpDirectSoundBuffer, IUnknown *pUnkOuter) PURE; \
+ STDMETHOD(CreateSoundBuffer)(THIS_ LPCDSBUFFERDESC lpcDSBufferDesc, LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer, IUnknown *pUnkOuter) PURE; \
STDMETHOD(GetCaps)(THIS_ LPDSCAPS lpDSCaps) PURE; \
- STDMETHOD(DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER8 lpDsbOriginal, LPLPDIRECTSOUNDBUFFER8 lplpDsbDuplicate) PURE; \
+ STDMETHOD(DuplicateSoundBuffer)(THIS_ LPDIRECTSOUNDBUFFER lpDsbOriginal, LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate) PURE; \
STDMETHOD(SetCooperativeLevel)(THIS_ HWND hwnd, DWORD dwLevel) PURE; \
STDMETHOD(Compact)(THIS) PURE; \
STDMETHOD(GetSpeakerConfig)(THIS_ LPDWORD lpdwSpeakerConfig) PURE; \
-------------- next part --------------
diff -u --unidirectional-new-file dlls/dsound/buffer.c /home/wine/wine.save6/dlls/dsound/buffer.c
--- dlls/dsound/buffer.c 2004-06-29 08:02:30.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/buffer.c 2004-03-10 18:39:27.000000000 -0500
@@ -100,7 +100,7 @@
ICOM_THIS(IDirectSoundNotifyImpl,iface);
TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);
- if (howmuch > 0 && notify == NULL) {
+ if (notify == NULL) {
WARN("invalid parameter: notify == NULL\n");
return DSERR_INVALIDPARAM;
}
@@ -118,7 +118,7 @@
if (hres != DS_OK)
WARN("IDsDriverNotify_SetNotificationPositions failed\n");
return hres;
- } else if (howmuch > 0) {
+ } else {
/* Make an internal copy of the caller-supplied array.
* Replace the existing copy if one is already present. */
if (This->dsb->notifies)
@@ -134,13 +134,7 @@
}
memcpy(This->dsb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
This->dsb->nrofnotifies = howmuch;
- } else {
- if (This->dsb->notifies) {
- HeapFree(GetProcessHeap(), 0, This->dsb->notifies);
- This->dsb->notifies = NULL;
- }
- This->dsb->nrofnotifies = 0;
- }
+ }
return S_OK;
}
Binary files dlls/dsound/buffer.o and /home/wine/wine.save6/dlls/dsound/buffer.o differ
diff -u --unidirectional-new-file dlls/dsound/capture.c /home/wine/wine.save6/dlls/dsound/capture.c
--- dlls/dsound/capture.c 2004-06-29 08:02:30.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/capture.c 2004-03-10 18:39:28.000000000 -0500
@@ -320,14 +320,18 @@
msg == MM_WIM_DATA ? "MM_WIM_DATA" : "UNKNOWN",dwUser,dw1,dw2,GetTickCount());
if (msg == MM_WIM_DATA) {
- LPWAVEHDR pHdr = (LPWAVEHDR)dw1;
EnterCriticalSection( &(This->lock) );
TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n",
captureStateString[This->state],This->index);
if (This->state != STATE_STOPPED) {
int index = This->index;
if (This->state == STATE_STARTING) {
- This->read_position = pHdr->dwBytesRecorded;
+ MMTIME mtime;
+ mtime.wType = TIME_BYTES;
+ waveInGetPosition(This->hwi, &mtime, sizeof(mtime));
+ TRACE("mtime.u.cb=%ld,This->buflen=%ld\n", mtime.u.cb, This->buflen);
+ mtime.u.cb = mtime.u.cb % This->buflen;
+ This->read_position = mtime.u.cb;
This->state = STATE_CAPTURING;
}
waveInUnprepareHeader(hwi,&(This->pwave[This->index]),sizeof(WAVEHDR));
@@ -667,8 +671,7 @@
return DSERR_INVALIDPARAM;
}
- if ( ((lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC)) &&
- (lpcDSCBufferDesc->dwSize != sizeof(DSCBUFFERDESC1))) ||
+ if ( (lpcDSCBufferDesc->dwSize < sizeof(DSCBUFFERDESC)) ||
(lpcDSCBufferDesc->dwBufferBytes == 0) ||
(lpcDSCBufferDesc->lpwfxFormat == NULL) ) {
WARN("invalid lpcDSCBufferDesc\n");
@@ -824,8 +827,6 @@
ref = InterlockedDecrement(&(This->ref));
if (ref == 0) {
- if (This->dscb->hwnotify)
- IDsDriverNotify_Release(This->dscb->hwnotify);
This->dscb->notify=NULL;
IDirectSoundCaptureBuffer_Release((LPDIRECTSOUNDCAPTUREBUFFER)This->dscb);
HeapFree(GetProcessHeap(),0,This);
@@ -842,7 +843,7 @@
ICOM_THIS(IDirectSoundCaptureNotifyImpl,iface);
TRACE("(%p,0x%08lx,%p)\n",This,howmuch,notify);
- if (howmuch > 0 && notify == NULL) {
+ if (notify == NULL) {
WARN("invalid parameter: notify == NULL\n");
return DSERR_INVALIDPARAM;
}
@@ -860,7 +861,7 @@
if (hres != DS_OK)
WARN("IDsDriverNotify_SetNotificationPositions failed\n");
return hres;
- } else if (howmuch > 0) {
+ } else {
/* Make an internal copy of the caller-supplied array.
* Replace the existing copy if one is already present. */
if (This->dscb->notifies)
@@ -876,12 +877,6 @@
}
memcpy(This->dscb->notifies, notify, howmuch * sizeof(DSBPOSITIONNOTIFY));
This->dscb->nrofnotifies = howmuch;
- } else {
- if (This->dscb->notifies) {
- HeapFree(GetProcessHeap(), 0, This->dscb->notifies);
- This->dscb->notifies = NULL;
- }
- This->dscb->nrofnotifies = 0;
}
return S_OK;
@@ -1370,11 +1365,6 @@
ipDSC->nrofpwaves*sizeof(WAVEHDR));
for (c = 0; c < ipDSC->nrofpwaves; c++) {
- if (This->notifies[c].dwOffset == DSBPN_OFFSETSTOP) {
- TRACE("got DSBPN_OFFSETSTOP\n");
- ipDSC->nrofpwaves = c;
- break;
- }
if (c == 0) {
ipDSC->pwave[0].lpData = ipDSC->buffer;
ipDSC->pwave[0].dwBufferLength =
@@ -1386,14 +1376,12 @@
This->notifies[c].dwOffset -
This->notifies[c-1].dwOffset;
}
- ipDSC->pwave[c].dwBytesRecorded = 0;
ipDSC->pwave[c].dwUser = (DWORD)ipDSC;
ipDSC->pwave[c].dwFlags = 0;
ipDSC->pwave[c].dwLoops = 0;
err = mmErr(waveInPrepareHeader(ipDSC->hwi,
&(ipDSC->pwave[c]),sizeof(WAVEHDR)));
if (err != DS_OK) {
- WARN("waveInPrepareHeader failed\n");
while (c--)
waveInUnprepareHeader(ipDSC->hwi,
&(ipDSC->pwave[c]),sizeof(WAVEHDR));
@@ -1403,7 +1391,6 @@
err = mmErr(waveInAddBuffer(ipDSC->hwi,
&(ipDSC->pwave[c]), sizeof(WAVEHDR)));
if (err != DS_OK) {
- WARN("waveInAddBuffer failed\n");
while (c--)
waveInUnprepareHeader(ipDSC->hwi,
&(ipDSC->pwave[c]),sizeof(WAVEHDR));
@@ -1424,7 +1411,6 @@
ipDSC->pwave[0].lpData = ipDSC->buffer;
ipDSC->pwave[0].dwBufferLength = ipDSC->buflen;
- ipDSC->pwave[0].dwBytesRecorded = 0;
ipDSC->pwave[0].dwUser = (DWORD)ipDSC;
ipDSC->pwave[0].dwFlags = 0;
ipDSC->pwave[0].dwLoops = 0;
@@ -1439,7 +1425,6 @@
err = mmErr(waveInAddBuffer(ipDSC->hwi,
&(ipDSC->pwave[0]), sizeof(WAVEHDR)));
if (err != DS_OK) {
- WARN("waveInAddBuffer failed\n");
waveInUnprepareHeader(ipDSC->hwi,
&(ipDSC->pwave[0]),sizeof(WAVEHDR));
}
@@ -1452,8 +1437,6 @@
if (err == DS_OK) {
/* start filling the first buffer */
err = mmErr(waveInStart(ipDSC->hwi));
- if (err != DS_OK)
- WARN("waveInStart failed\n");
}
}
@@ -1687,7 +1670,7 @@
IClassFactoryImpl DSOUND_CAPTURE_CF = { &DSCCF_Vtbl, 1 };
/***************************************************************************
- * DirectSoundFullDuplexCreate [DSOUND.10]
+ * DirectSoundFullDuplexCreate8 [DSOUND.10]
*
* Create and initialize a DirectSoundFullDuplex interface.
*
@@ -1709,7 +1692,7 @@
* DSERR_OUTOFMEMORY DSERR_INVALIDCALL DSERR_NODRIVER
*/
HRESULT WINAPI
-DirectSoundFullDuplexCreate(
+DirectSoundFullDuplexCreate8(
LPCGUID pcGuidCaptureDevice,
LPCGUID pcGuidRenderDevice,
LPCDSCBUFFERDESC pcDSCBufferDesc,
Binary files dlls/dsound/capture.o and /home/wine/wine.save6/dlls/dsound/capture.o differ
Common subdirectories: dlls/dsound/CVS and /home/wine/wine.save6/dlls/dsound/CVS
diff -u --unidirectional-new-file dlls/dsound/.cvsignore /home/wine/wine.save6/dlls/dsound/.cvsignore
--- dlls/dsound/.cvsignore 2004-05-29 18:35:41.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/.cvsignore 2004-03-10 18:39:27.000000000 -0500
@@ -1,4 +1,5 @@
Makefile
dsound.dll.dbg.c
+dsound.spec.c
dsound.spec.def
version.res
Only in dlls/dsound: dsound.c
Binary files dlls/dsound/dsound.dll.so and /home/wine/wine.save6/dlls/dsound/dsound.dll.so differ
diff -u --unidirectional-new-file dlls/dsound/dsound_main.c /home/wine/wine.save6/dlls/dsound/dsound_main.c
--- dlls/dsound/dsound_main.c 2004-06-30 15:59:46.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/dsound_main.c 2004-03-16 21:16:30.000000000 -0500
@@ -143,7 +143,6 @@
{
char buffer[MAX_PATH+1];
HKEY hkey, appkey = 0;
- DWORD len;
buffer[MAX_PATH]='\0';
@@ -154,8 +153,7 @@
ExitProcess(1);
}
- len = GetModuleFileNameA( 0, buffer, MAX_PATH );
- if (len && len < MAX_PATH)
+ if (GetModuleFileNameA( 0, buffer, MAX_PATH ))
{
HKEY tmpkey;
@@ -438,6 +436,764 @@
return DS_OK;
}
+
+static void _dump_DSBCAPS(DWORD xmask) {
+ struct {
+ DWORD mask;
+ char *name;
+ } flags[] = {
+#define FE(x) { x, #x },
+ FE(DSBCAPS_PRIMARYBUFFER)
+ FE(DSBCAPS_STATIC)
+ FE(DSBCAPS_LOCHARDWARE)
+ FE(DSBCAPS_LOCSOFTWARE)
+ FE(DSBCAPS_CTRL3D)
+ FE(DSBCAPS_CTRLFREQUENCY)
+ FE(DSBCAPS_CTRLPAN)
+ FE(DSBCAPS_CTRLVOLUME)
+ FE(DSBCAPS_CTRLPOSITIONNOTIFY)
+ FE(DSBCAPS_CTRLDEFAULT)
+ FE(DSBCAPS_CTRLALL)
+ FE(DSBCAPS_STICKYFOCUS)
+ FE(DSBCAPS_GLOBALFOCUS)
+ FE(DSBCAPS_GETCURRENTPOSITION2)
+ FE(DSBCAPS_MUTE3DATMAXDISTANCE)
+#undef FE
+ };
+ int i;
+
+ for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+ if ((flags[i].mask & xmask) == flags[i].mask)
+ DPRINTF("%s ",flags[i].name);
+}
+
+/*******************************************************************************
+ * IDirectSound
+ */
+
+static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
+ LPDIRECTSOUND8 iface,HWND hwnd,DWORD level
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%08lx,%ld)\n",This,(DWORD)hwnd,level);
+
+ if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
+ FIXME("level=%s not fully supported\n",
+ level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
+ }
+
+ This->priolevel = level;
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
+ LPDIRECTSOUND8 iface,LPCDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER8 ppdsb,LPUNKNOWN lpunk
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ LPWAVEFORMATEX wfex;
+ HRESULT hres = DS_OK;
+
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsbd == NULL) {
+ WARN("invalid parameter: dsbd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (TRACE_ON(dsound)) {
+ TRACE("(structsize=%ld)\n",dsbd->dwSize);
+ TRACE("(flags=0x%08lx:\n",dsbd->dwFlags);
+ _dump_DSBCAPS(dsbd->dwFlags);
+ DPRINTF(")\n");
+ TRACE("(bufferbytes=%ld)\n",dsbd->dwBufferBytes);
+ TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
+ }
+
+ wfex = dsbd->lpwfxFormat;
+
+ if (wfex)
+ TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
+ "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
+ wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
+ wfex->nAvgBytesPerSec, wfex->nBlockAlign,
+ wfex->wBitsPerSample, wfex->cbSize);
+
+ if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
+ if (This->primary) {
+ WARN("Primary Buffer already created\n");
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+ *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
+ } else {
+ This->dsbd = *dsbd;
+ hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
+ if (This->primary) {
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+ *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
+ } else
+ WARN("PrimaryBufferImpl_Create failed\n");
+ }
+ } else {
+ IDirectSoundBufferImpl * dsb;
+ hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
+ if (dsb) {
+ hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+ if (*ppdsb) {
+ dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+ } else
+ WARN("SecondaryBufferImpl_Create failed\n");
+ } else
+ WARN("IDirectSoundBufferImpl_Create failed\n");
+ }
+
+ return hres;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
+ LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 psb,LPLPDIRECTSOUNDBUFFER8 ppdsb
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ IDirectSoundBufferImpl* pdsb;
+ IDirectSoundBufferImpl* dsb;
+ HRESULT hres = DS_OK;
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (psb == NULL) {
+ WARN("invalid parameter: psb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* FIXME: hack to make sure we have a secondary buffer */
+ if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
+ ERR("trying to duplicate primary buffer\n");
+ *ppdsb = NULL;
+ return DSERR_INVALIDCALL;
+ }
+
+ pdsb = ((SecondaryBufferImpl *)psb)->dsb;
+
+ dsb = (IDirectSoundBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
+
+ if (dsb == NULL) {
+ WARN("out of memory\n");
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
+
+ if (pdsb->hwbuf) {
+ TRACE("duplicating hardware buffer\n");
+
+ hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
+ if (hres != DS_OK) {
+ TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
+ dsb->hwbuf = NULL;
+ /* allocate buffer */
+ if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
+ dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
+ if (dsb->buffer == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
+ if (dsb->buffer->memory == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb->buffer);
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+ dsb->buffer->ref = 1;
+
+ /* FIXME: copy buffer ? */
+ }
+ }
+ } else {
+ dsb->hwbuf = NULL;
+ dsb->buffer->ref++;
+ }
+
+ dsb->ref = 0;
+ dsb->state = STATE_STOPPED;
+ dsb->playpos = 0;
+ dsb->buf_mixpos = 0;
+ dsb->dsound = This;
+ dsb->ds3db = NULL;
+ dsb->iks = NULL; /* FIXME? */
+ dsb->dsb = NULL;
+ memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
+ InitializeCriticalSection(&(dsb->lock));
+ /* register buffer */
+ RtlAcquireResourceExclusive(&(This->lock), TRUE);
+ {
+ IDirectSoundBufferImpl **newbuffers;
+ if (This->buffers)
+ newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
+ else
+ newbuffers = (IDirectSoundBufferImpl**)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
+
+ if (newbuffers) {
+ This->buffers = newbuffers;
+ This->buffers[This->nrofbuffers] = dsb;
+ This->nrofbuffers++;
+ TRACE("buffer count is now %d\n", This->nrofbuffers);
+ } else {
+ ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers);
+ IDirectSoundBuffer8_Release(psb);
+ DeleteCriticalSection(&(dsb->lock));
+ RtlReleaseResource(&(This->lock));
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = 0;
+ return DSERR_OUTOFMEMORY;
+ }
+ }
+ RtlReleaseResource(&(This->lock));
+ IDirectSound_AddRef(iface);
+ hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+ if (*ppdsb) {
+ dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+ } else
+ WARN("SecondaryBufferImpl_Create failed\n");
+
+ return hres;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS lpDSCaps) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (lpDSCaps == NULL) {
+ WARN("invalid parameter: lpDSCaps = NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* check is there is enough room */
+ if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
+ WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
+ lpDSCaps->dwSize, sizeof(*lpDSCaps));
+ return DSERR_INVALIDPARAM;
+ }
+
+ lpDSCaps->dwFlags = This->drvcaps.dwFlags;
+ TRACE("(flags=0x%08lx)\n",lpDSCaps->dwFlags);
+
+ lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
+ lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
+
+ lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
+
+ lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
+ lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
+ lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
+
+ lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
+ lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
+ lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
+
+ lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
+ lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
+ lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
+
+ lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
+ lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
+ lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
+
+ lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
+
+ lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
+
+ lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
+
+ /* driver doesn't have these */
+ lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
+
+ lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
+
+ return DS_OK;
+}
+
+static ULONG WINAPI IDirectSoundImpl_AddRef(LPDIRECTSOUND8 iface) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ ULONG ulReturn;
+
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ HRESULT hres;
+ UINT i;
+
+ timeKillEvent(This->timerID);
+ timeEndPeriod(DS_TIME_RES);
+ /* wait for timer to expire */
+ Sleep(DS_TIME_RES+1);
+
+ RtlAcquireResourceShared(&(This->lock), TRUE);
+
+ if (This->buffers) {
+ for( i=0;i<This->nrofbuffers;i++)
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
+ }
+
+ RtlReleaseResource(&(This->lock));
+
+ if (This->primary) {
+ WARN("primary buffer not released\n");
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
+ }
+
+ hres = DSOUND_PrimaryDestroy(This);
+ if (hres != DS_OK)
+ WARN("DSOUND_PrimaryDestroy failed\n");
+
+ if (This->driver)
+ IDsDriver_Close(This->driver);
+
+ if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ waveOutClose(This->hwo);
+
+ if (This->driver)
+ IDsDriver_Release(This->driver);
+
+ RtlDeleteResource(&This->lock);
+ DeleteCriticalSection(&This->mixlock);
+ HeapFree(GetProcessHeap(),0,This);
+ dsound = NULL;
+ TRACE("(%p) released\n",This);
+ }
+
+ return ulReturn;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
+ LPDIRECTSOUND8 iface,DWORD config
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,0x%08lx)\n",This,config);
+
+ This->speaker_config = config;
+
+ WARN("not fully functional\n");
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
+ LPDIRECTSOUND8 iface,REFIID riid,LPVOID *ppobj
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
+ }
+
+ *ppobj = NULL; /* assume failure */
+
+ if ( IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IDirectSound) ||
+ IsEqualGUID(riid, &IID_IDirectSound8) ) {
+ IDirectSound8_AddRef((LPDIRECTSOUND8)This);
+ *ppobj = This;
+ return S_OK;
+ }
+
+ if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
+ WARN("app requested IDirectSound3DListener on dsound object\n");
+ return E_NOINTERFACE;
+ }
+
+ FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_Compact(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p)\n", This);
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+
+ if (lpdwSpeakerConfig == NULL) {
+ WARN("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ WARN("not fully functional\n");
+
+ *lpdwSpeakerConfig = This->speaker_config;
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_Initialize(
+ LPDIRECTSOUND8 iface,
+ LPCGUID lpcGuid)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
+ LPDIRECTSOUND8 iface,
+ LPDWORD pdwCertified)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %p)\n", This, pdwCertified);
+ *pdwCertified = DS_CERTIFIED;
+ return DS_OK;
+}
+
+static ICOM_VTABLE(IDirectSound8) dsvt =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IDirectSoundImpl_QueryInterface,
+ IDirectSoundImpl_AddRef,
+ IDirectSoundImpl_Release,
+ IDirectSoundImpl_CreateSoundBuffer,
+ IDirectSoundImpl_GetCaps,
+ IDirectSoundImpl_DuplicateSoundBuffer,
+ IDirectSoundImpl_SetCooperativeLevel,
+ IDirectSoundImpl_Compact,
+ IDirectSoundImpl_GetSpeakerConfig,
+ IDirectSoundImpl_SetSpeakerConfig,
+ IDirectSoundImpl_Initialize,
+ IDirectSoundImpl_VerifyCertification
+};
+
+
+/*******************************************************************************
+ * DirectSoundCreate (DSOUND.1)
+ *
+ * Creates and initializes a DirectSound interface.
+ *
+ * PARAMS
+ * lpcGUID [I] Address of the GUID that identifies the sound device.
+ * ppDS [O] Address of a variable to receive the interface pointer.
+ * pUnkOuter [I] Must be NULL.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
+ * DSERR_NODRIVER, DSERR_OUTOFMEMORY
+ */
+HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
+{
+ IDirectSoundImpl** ippDS=(IDirectSoundImpl**)ppDS;
+ PIDSDRIVER drv = NULL;
+ unsigned wod, wodn;
+ HRESULT err = DSERR_INVALIDPARAM;
+ GUID devGuid;
+ BOOLEAN found = FALSE;
+
+ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ippDS,pUnkOuter);
+
+ if (ippDS == NULL) {
+ WARN("invalid parameter: ippDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ /* Default device? */
+ if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
+ lpcGUID = &DSDEVID_DefaultPlayback;
+
+ if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
+ WARN("invalid parameter: lpcGUID\n");
+ *ippDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsound) {
+ if (IsEqualGUID(&devGuid, &dsound->guid) ) {
+ /* FIXME: this is wrong, need to create a new instance */
+ ERR("dsound already opened\n");
+ IDirectSound_AddRef((LPDIRECTSOUND)dsound);
+ *ippDS = dsound;
+ return DS_OK;
+ } else {
+ ERR("different dsound already opened\n");
+ }
+ }
+
+ /* Enumerate WINMM audio devices and find the one we want */
+ wodn = waveOutGetNumDevs();
+ if (!wodn) {
+ WARN("no driver\n");
+ *ippDS = NULL;
+ return DSERR_NODRIVER;
+ }
+
+ TRACE(" expecting GUID %s.\n", debugstr_guid(&devGuid));
+
+ for (wod=0; wod<wodn; wod++) {
+ GUID guid;
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
+ if (err != DS_OK) {
+ WARN("waveOutMessage failed; err=%lx\n",err);
+ *ippDS = NULL;
+ return err;
+ }
+ TRACE("got GUID %s for wod %d.\n", debugstr_guid(&guid), wod);
+ if (IsEqualGUID( &devGuid, &guid) ) {
+ err = DS_OK;
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (err != DS_OK) {
+ WARN("invalid parameter\n");
+ *ippDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (found == FALSE) {
+ WARN("No device found matching given ID - trying with default one !\n");
+ wod = ds_default_playback;
+ }
+
+ /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
+ waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
+
+ /* Disable the direct sound driver to force emulation if requested. */
+ if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
+ drv = NULL;
+
+ /* Allocate memory */
+ *ippDS = (IDirectSoundImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
+ if (*ippDS == NULL) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
+ }
+
+ (*ippDS)->lpVtbl = &dsvt;
+ (*ippDS)->ref = 1;
+
+ (*ippDS)->driver = drv;
+ (*ippDS)->priolevel = DSSCL_NORMAL;
+ (*ippDS)->fraglen = 0;
+ (*ippDS)->hwbuf = NULL;
+ (*ippDS)->buffer = NULL;
+ (*ippDS)->buflen = 0;
+ (*ippDS)->writelead = 0;
+ (*ippDS)->state = STATE_STOPPED;
+ (*ippDS)->nrofbuffers = 0;
+ (*ippDS)->buffers = NULL;
+ (*ippDS)->primary = NULL;
+ (*ippDS)->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
+
+ /* 3D listener initial parameters */
+ (*ippDS)->listener = NULL;
+ (*ippDS)->ds3dl.dwSize = sizeof(DS3DLISTENER);
+ (*ippDS)->ds3dl.vPosition.x = 0.0;
+ (*ippDS)->ds3dl.vPosition.y = 0.0;
+ (*ippDS)->ds3dl.vPosition.z = 0.0;
+ (*ippDS)->ds3dl.vVelocity.x = 0.0;
+ (*ippDS)->ds3dl.vVelocity.y = 0.0;
+ (*ippDS)->ds3dl.vVelocity.z = 0.0;
+ (*ippDS)->ds3dl.vOrientFront.x = 0.0;
+ (*ippDS)->ds3dl.vOrientFront.y = 0.0;
+ (*ippDS)->ds3dl.vOrientFront.z = 1.0;
+ (*ippDS)->ds3dl.vOrientTop.x = 0.0;
+ (*ippDS)->ds3dl.vOrientTop.y = 1.0;
+ (*ippDS)->ds3dl.vOrientTop.z = 0.0;
+ (*ippDS)->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
+ (*ippDS)->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
+ (*ippDS)->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
+
+ (*ippDS)->prebuf = ds_snd_queue_max;
+ (*ippDS)->guid = devGuid;
+
+ /* Get driver description */
+ if (drv) {
+ err = IDsDriver_GetDriverDesc(drv,&((*ippDS)->drvdesc));
+ if (err != DS_OK) {
+ WARN("IDsDriver_GetDriverDesc failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ } else {
+ /* if no DirectSound interface available, use WINMM API instead */
+ (*ippDS)->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
+ }
+
+ (*ippDS)->drvdesc.dnDevNode = wod;
+
+ /* Set default wave format (may need it for waveOutOpen) */
+ (*ippDS)->wfx.wFormatTag = WAVE_FORMAT_PCM;
+ /* We rely on the sound driver to return the actual sound format of
+ * the device if it does not support 22050x8x2 and is given the
+ * WAVE_DIRECTSOUND flag.
+ */
+ (*ippDS)->wfx.nSamplesPerSec = 22050;
+ (*ippDS)->wfx.wBitsPerSample = 8;
+ (*ippDS)->wfx.nChannels = 2;
+ (*ippDS)->wfx.nBlockAlign = (*ippDS)->wfx.wBitsPerSample * (*ippDS)->wfx.nChannels / 8;
+ (*ippDS)->wfx.nAvgBytesPerSec = (*ippDS)->wfx.nSamplesPerSec * (*ippDS)->wfx.nBlockAlign;
+ (*ippDS)->wfx.cbSize = 0;
+
+ /* If the driver requests being opened through MMSYSTEM
+ * (which is recommended by the DDK), it is supposed to happen
+ * before the DirectSound interface is opened */
+ if ((*ippDS)->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ {
+ DWORD flags = CALLBACK_FUNCTION;
+
+ /* disable direct sound if requested */
+ if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
+ flags |= WAVE_DIRECTSOUND;
+
+ err = mmErr(waveOutOpen(&((*ippDS)->hwo),
+ (*ippDS)->drvdesc.dnDevNode, &((*ippDS)->wfx),
+ (DWORD)DSOUND_callback, (DWORD)(*ippDS),
+ flags));
+ if (err != DS_OK) {
+ WARN("waveOutOpen failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ }
+
+ if (drv) {
+ err = IDsDriver_Open(drv);
+ if (err != DS_OK) {
+ WARN("IDsDriver_Open failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+
+ /* the driver is now open, so it's now allowed to call GetCaps */
+ err = IDsDriver_GetCaps(drv,&((*ippDS)->drvcaps));
+ if (err != DS_OK) {
+ WARN("IDsDriver_GetCaps failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ } else {
+ WAVEOUTCAPSA woc;
+ err = mmErr(waveOutGetDevCapsA((*ippDS)->drvdesc.dnDevNode, &woc, sizeof(woc)));
+ if (err != DS_OK) {
+ WARN("waveOutGetDevCaps failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ ZeroMemory(&(*ippDS)->drvcaps, sizeof((*ippDS)->drvcaps));
+ if ((woc.dwFormats & WAVE_FORMAT_1M08) ||
+ (woc.dwFormats & WAVE_FORMAT_2M08) ||
+ (woc.dwFormats & WAVE_FORMAT_4M08) ||
+ (woc.dwFormats & WAVE_FORMAT_48M08) ||
+ (woc.dwFormats & WAVE_FORMAT_96M08)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1M16) ||
+ (woc.dwFormats & WAVE_FORMAT_2M16) ||
+ (woc.dwFormats & WAVE_FORMAT_4M16) ||
+ (woc.dwFormats & WAVE_FORMAT_48M16) ||
+ (woc.dwFormats & WAVE_FORMAT_96M16)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1S08) ||
+ (woc.dwFormats & WAVE_FORMAT_2S08) ||
+ (woc.dwFormats & WAVE_FORMAT_4S08) ||
+ (woc.dwFormats & WAVE_FORMAT_48S08) ||
+ (woc.dwFormats & WAVE_FORMAT_96S08)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1S16) ||
+ (woc.dwFormats & WAVE_FORMAT_2S16) ||
+ (woc.dwFormats & WAVE_FORMAT_4S16) ||
+ (woc.dwFormats & WAVE_FORMAT_48S16) ||
+ (woc.dwFormats & WAVE_FORMAT_96S16)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
+ }
+ if (ds_emuldriver)
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
+ (*ippDS)->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
+ (*ippDS)->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
+ (*ippDS)->drvcaps.dwPrimaryBuffers = 1;
+ }
+
+ (*ippDS)->volpan.lVolume = 0;
+ (*ippDS)->volpan.lPan = 0;
+ DSOUND_RecalcVolPan(&((*ippDS)->volpan));
+
+ InitializeCriticalSection(&((*ippDS)->mixlock));
+ RtlInitializeResource(&((*ippDS)->lock));
+
+ if (!dsound) {
+ HRESULT hres;
+ dsound = (*ippDS);
+ hres = DSOUND_PrimaryCreate(dsound);
+ if (hres != DS_OK) {
+ WARN("DSOUND_PrimaryCreate failed\n");
+ return hres;
+ }
+ timeBeginPeriod(DS_TIME_RES);
+ dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
+ (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+ }
+
+ return DS_OK;
+}
+
+
/*******************************************************************************
* DirectSound ClassFactory
*/
diff -u --unidirectional-new-file dlls/dsound/.#dsound_main.c.1.96 /home/wine/wine.save6/dlls/dsound/.#dsound_main.c.1.96
--- dlls/dsound/.#dsound_main.c.1.96 1969-12-31 19:00:00.000000000 -0500
+++ /home/wine/wine.save6/dlls/dsound/.#dsound_main.c.1.96 2004-03-16 19:25:04.000000000 -0500
@@ -0,0 +1,1421 @@
+/* DirectSound
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998 Rob Riggs
+ * Copyright 2000-2002 TransGaming Technologies, Inc.
+ *
+ * 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 3D 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 "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#define NONAMELESSSTRUCT
+#define NONAMELESSUNION
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "winuser.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "mmsystem.h"
+#include "winternl.h"
+#include "mmddk.h"
+#include "wine/windef16.h"
+#include "wine/winbase16.h"
+#include "wine/debug.h"
+#include "dsound.h"
+#include "dsdriver.h"
+#include "dsound_private.h"
+#include "dsconf.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dsound);
+
+/* these are eligible for tuning... they must be high on slow machines... */
+/* some stuff may get more responsive with lower values though... */
+#define DS_EMULDRIVER 0 /* some games (Quake 2, UT) refuse to accept
+ emulated dsound devices. set to 0 ! */
+#define DS_HEL_MARGIN 5 /* HEL only: number of waveOut fragments ahead to mix in new buffers
+ * (keep this close or equal to DS_HEL_QUEUE for best results) */
+#define DS_HEL_QUEUE 5 /* HEL only: number of waveOut fragments ahead to queue to driver
+ * (this will affect HEL sound reliability and latency) */
+
+#define DS_SND_QUEUE_MAX 28 /* max number of fragments to prebuffer */
+#define DS_SND_QUEUE_MIN 12 /* min number of fragments to prebuffer */
+
+IDirectSoundImpl* dsound = NULL;
+
+HRESULT mmErr(UINT err)
+{
+ switch(err) {
+ case MMSYSERR_NOERROR:
+ return DS_OK;
+ case MMSYSERR_ALLOCATED:
+ return DSERR_ALLOCATED;
+ case MMSYSERR_ERROR:
+ case MMSYSERR_INVALHANDLE:
+ case WAVERR_STILLPLAYING:
+ return DSERR_GENERIC; /* FIXME */
+ case MMSYSERR_NODRIVER:
+ return DSERR_NODRIVER;
+ case MMSYSERR_NOMEM:
+ return DSERR_OUTOFMEMORY;
+ case MMSYSERR_INVALPARAM:
+ case WAVERR_BADFORMAT:
+ case WAVERR_UNPREPARED:
+ return DSERR_INVALIDPARAM;
+ case MMSYSERR_NOTSUPPORTED:
+ return DSERR_UNSUPPORTED;
+ default:
+ FIXME("Unknown MMSYS error %d\n",err);
+ return DSERR_GENERIC;
+ }
+}
+
+int ds_emuldriver = DS_EMULDRIVER;
+int ds_hel_margin = DS_HEL_MARGIN;
+int ds_hel_queue = DS_HEL_QUEUE;
+int ds_snd_queue_max = DS_SND_QUEUE_MAX;
+int ds_snd_queue_min = DS_SND_QUEUE_MIN;
+int ds_hw_accel = DS_HW_ACCEL_FULL;
+int ds_default_playback = 0;
+int ds_default_capture = 0;
+
+/*
+ * Get a config key from either the app-specific or the default config
+ */
+
+inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
+ char *buffer, DWORD size )
+{
+ if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, buffer, &size )) return 0;
+ return RegQueryValueExA( defkey, name, 0, NULL, buffer, &size );
+}
+
+
+/*
+ * Setup the dsound options.
+ */
+
+void setup_dsound_options(void)
+{
+ char buffer[MAX_PATH+1];
+ HKEY hkey, appkey = 0;
+
+ buffer[MAX_PATH]='\0';
+
+ if (RegCreateKeyExA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\dsound", 0, NULL,
+ REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL ))
+ {
+ ERR("Cannot create config registry key\n" );
+ ExitProcess(1);
+ }
+
+ if (GetModuleFileNameA( 0, buffer, MAX_PATH ))
+ {
+ HKEY tmpkey;
+
+ if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\AppDefaults", &tmpkey ))
+ {
+ char appname[MAX_PATH+16];
+ char *p = strrchr( buffer, '\\' );
+ if (p!=NULL) {
+ appname[MAX_PATH]='\0';
+ strncpy(appname,p+1,MAX_PATH);
+ strcat(appname,"\\dsound");
+ TRACE("appname = [%s] \n",appname);
+ if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
+ RegCloseKey( tmpkey );
+ }
+ }
+ }
+
+ /* get options */
+
+ if (!get_config_key( hkey, appkey, "EmulDriver", buffer, MAX_PATH ))
+ ds_emuldriver = strcmp(buffer, "N");
+
+ if (!get_config_key( hkey, appkey, "HELmargin", buffer, MAX_PATH ))
+ ds_hel_margin = atoi(buffer);
+
+ if (!get_config_key( hkey, appkey, "HELqueue", buffer, MAX_PATH ))
+ ds_hel_queue = atoi(buffer);
+
+ if (!get_config_key( hkey, appkey, "SndQueueMax", buffer, MAX_PATH ))
+ ds_snd_queue_max = atoi(buffer);
+
+ if (!get_config_key( hkey, appkey, "SndQueueMin", buffer, MAX_PATH ))
+ ds_snd_queue_min = atoi(buffer);
+
+ if (!get_config_key( hkey, appkey, "HardwareAcceleration", buffer, MAX_PATH )) {
+ if (strcmp(buffer, "Full") == 0)
+ ds_hw_accel = DS_HW_ACCEL_FULL;
+ else if (strcmp(buffer, "Standard") == 0)
+ ds_hw_accel = DS_HW_ACCEL_STANDARD;
+ else if (strcmp(buffer, "Basic") == 0)
+ ds_hw_accel = DS_HW_ACCEL_BASIC;
+ else if (strcmp(buffer, "Emulation") == 0)
+ ds_hw_accel = DS_HW_ACCEL_EMULATION;
+ }
+
+ if (!get_config_key( hkey, appkey, "DefaultPlayback", buffer, MAX_PATH ))
+ ds_default_playback = atoi(buffer);
+
+ if (!get_config_key( hkey, appkey, "DefaultCapture", buffer, MAX_PATH ))
+ ds_default_capture = atoi(buffer);
+
+ if (appkey) RegCloseKey( appkey );
+ RegCloseKey( hkey );
+
+ if (ds_emuldriver != DS_EMULDRIVER )
+ WARN("ds_emuldriver = %d (default=%d)\n",ds_emuldriver, DS_EMULDRIVER);
+ if (ds_hel_margin != DS_HEL_MARGIN )
+ WARN("ds_hel_margin = %d (default=%d)\n",ds_hel_margin, DS_HEL_MARGIN );
+ if (ds_hel_queue != DS_HEL_QUEUE )
+ WARN("ds_hel_queue = %d (default=%d)\n",ds_hel_queue, DS_HEL_QUEUE );
+ if (ds_snd_queue_max != DS_SND_QUEUE_MAX)
+ WARN("ds_snd_queue_max = %d (default=%d)\n",ds_snd_queue_max ,DS_SND_QUEUE_MAX);
+ if (ds_snd_queue_min != DS_SND_QUEUE_MIN)
+ WARN("ds_snd_queue_min = %d (default=%d)\n",ds_snd_queue_min ,DS_SND_QUEUE_MIN);
+ if (ds_hw_accel != DS_HW_ACCEL_FULL)
+ WARN("ds_hw_accel = %s (default=Full)\n",
+ ds_hw_accel==DS_HW_ACCEL_FULL ? "Full" :
+ ds_hw_accel==DS_HW_ACCEL_STANDARD ? "Standard" :
+ ds_hw_accel==DS_HW_ACCEL_BASIC ? "Basic" :
+ ds_hw_accel==DS_HW_ACCEL_EMULATION ? "Emulation" :
+ "Unknown");
+ if (ds_default_playback != 0)
+ WARN("ds_default_playback = %d (default=0)\n",ds_default_playback);
+ if (ds_default_capture != 0)
+ WARN("ds_default_capture = %d (default=0)\n",ds_default_playback);
+}
+
+
+
+/***************************************************************************
+ * GetDeviceID [DSOUND.9]
+ *
+ * Retrieves unique identifier of default device specified
+ *
+ * PARAMS
+ * pGuidSrc [I] Address of device GUID.
+ * pGuidDest [O] Address to receive unique device GUID.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_INVALIDPARAM
+ *
+ * NOTES
+ * pGuidSrc is a valid device GUID or DSDEVID_DefaultPlayback,
+ * DSDEVID_DefaultCapture, DSDEVID_DefaultVoicePlayback, or
+ * DSDEVID_DefaultVoiceCapture.
+ * Returns pGuidSrc if pGuidSrc is a valid device or the device
+ * GUID for the specified constants.
+ */
+HRESULT WINAPI GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
+{
+ TRACE("(%p,%p)\n",pGuidSrc,pGuidDest);
+
+ if ( pGuidSrc == NULL) {
+ WARN("invalid parameter: pGuidSrc == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if ( pGuidDest == NULL ) {
+ WARN("invalid parameter: pGuidDest == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if ( IsEqualGUID( &DSDEVID_DefaultPlayback, pGuidSrc ) ||
+ IsEqualGUID( &DSDEVID_DefaultVoicePlayback, pGuidSrc ) ) {
+ GUID guid;
+ int err = mmErr(waveOutMessage((HWAVEOUT)ds_default_playback,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
+ if (err == DS_OK) {
+ memcpy(pGuidDest, &guid, sizeof(GUID));
+ return DS_OK;
+ }
+ }
+
+ if ( IsEqualGUID( &DSDEVID_DefaultCapture, pGuidSrc ) ||
+ IsEqualGUID( &DSDEVID_DefaultVoiceCapture, pGuidSrc ) ) {
+ GUID guid;
+ int err = mmErr(waveInMessage((HWAVEIN)ds_default_capture,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
+ if (err == DS_OK) {
+ memcpy(pGuidDest, &guid, sizeof(GUID));
+ return DS_OK;
+ }
+ }
+
+ memcpy(pGuidDest, pGuidSrc, sizeof(GUID));
+
+ return DS_OK;
+}
+
+
+/***************************************************************************
+ * DirectSoundEnumerateA [DSOUND.2]
+ *
+ * Enumerate all DirectSound drivers installed in the system
+ *
+ * PARAMS
+ * lpDSEnumCallback [I] Address of callback function.
+ * lpContext [I] Address of user defined context passed to callback function.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_INVALIDPARAM
+ */
+HRESULT WINAPI DirectSoundEnumerateA(
+ LPDSENUMCALLBACKA lpDSEnumCallback,
+ LPVOID lpContext)
+{
+ unsigned devs, wod;
+ DSDRIVERDESC desc;
+ GUID guid;
+ int err;
+
+ TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
+ lpDSEnumCallback, lpContext);
+
+ if (lpDSEnumCallback == NULL) {
+ WARN("invalid parameter: lpDSEnumCallback == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ devs = waveOutGetNumDevs();
+ if (devs > 0) {
+ if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
+ GUID temp;
+ for (wod = 0; wod < devs; ++wod) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
+ if (err == DS_OK) {
+ if (IsEqualGUID( &guid, &temp ) ) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
+ if (err == DS_OK) {
+ TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
+ "Primary Sound Driver",desc.szDrvName,lpContext);
+ if (lpDSEnumCallback(NULL, "Primary Sound Driver", desc.szDrvName, lpContext) == FALSE)
+ return DS_OK;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (wod = 0; wod < devs; ++wod) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
+ if (err == DS_OK) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
+ if (err == DS_OK) {
+ TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
+ debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
+ if (lpDSEnumCallback(&guid, desc.szDesc, desc.szDrvName, lpContext) == FALSE)
+ return DS_OK;
+ }
+ }
+ }
+ return DS_OK;
+}
+
+/***************************************************************************
+ * DirectSoundEnumerateW [DSOUND.3]
+ *
+ * Enumerate all DirectSound drivers installed in the system
+ *
+ * PARAMS
+ * lpDSEnumCallback [I] Address of callback function.
+ * lpContext [I] Address of user defined context passed to callback function.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_INVALIDPARAM
+ */
+HRESULT WINAPI DirectSoundEnumerateW(
+ LPDSENUMCALLBACKW lpDSEnumCallback,
+ LPVOID lpContext )
+{
+ unsigned devs, wod;
+ DSDRIVERDESC desc;
+ GUID guid;
+ int err;
+ WCHAR wDesc[MAXPNAMELEN];
+ WCHAR wName[MAXPNAMELEN];
+
+ TRACE("lpDSEnumCallback = %p, lpContext = %p\n",
+ lpDSEnumCallback, lpContext);
+
+ if (lpDSEnumCallback == NULL) {
+ WARN("invalid parameter: lpDSEnumCallback == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ devs = waveOutGetNumDevs();
+ if (devs > 0) {
+ if (GetDeviceID(&DSDEVID_DefaultPlayback, &guid) == DS_OK) {
+ GUID temp;
+ for (wod = 0; wod < devs; ++wod) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&temp,0));
+ if (err == DS_OK) {
+ if (IsEqualGUID( &guid, &temp ) ) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
+ if (err == DS_OK) {
+ TRACE("calling lpDSEnumCallback(NULL,\"%s\",\"%s\",%p)\n",
+ "Primary Sound Driver",desc.szDrvName,lpContext);
+ MultiByteToWideChar( CP_ACP, 0, "Primary Sound Driver", -1,
+ wDesc, sizeof(wDesc)/sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
+ wName, sizeof(wName)/sizeof(WCHAR) );
+ if (lpDSEnumCallback(NULL, wDesc, wName, lpContext) == FALSE)
+ return DS_OK;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ for (wod = 0; wod < devs; ++wod) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDDESC,(DWORD)&desc,0));
+ if (err == DS_OK) {
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)&guid,0));
+ if (err == DS_OK) {
+ TRACE("calling lpDSEnumCallback(%s,\"%s\",\"%s\",%p)\n",
+ debugstr_guid(&guid),desc.szDesc,desc.szDrvName,lpContext);
+ MultiByteToWideChar( CP_ACP, 0, desc.szDesc, -1,
+ wDesc, sizeof(wDesc)/sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, desc.szDrvName, -1,
+ wName, sizeof(wName)/sizeof(WCHAR) );
+ if (lpDSEnumCallback(&guid, wDesc, wName, lpContext) == FALSE)
+ return DS_OK;
+ }
+ }
+ }
+ return DS_OK;
+}
+
+
+static void _dump_DSBCAPS(DWORD xmask) {
+ struct {
+ DWORD mask;
+ char *name;
+ } flags[] = {
+#define FE(x) { x, #x },
+ FE(DSBCAPS_PRIMARYBUFFER)
+ FE(DSBCAPS_STATIC)
+ FE(DSBCAPS_LOCHARDWARE)
+ FE(DSBCAPS_LOCSOFTWARE)
+ FE(DSBCAPS_CTRL3D)
+ FE(DSBCAPS_CTRLFREQUENCY)
+ FE(DSBCAPS_CTRLPAN)
+ FE(DSBCAPS_CTRLVOLUME)
+ FE(DSBCAPS_CTRLPOSITIONNOTIFY)
+ FE(DSBCAPS_CTRLDEFAULT)
+ FE(DSBCAPS_CTRLALL)
+ FE(DSBCAPS_STICKYFOCUS)
+ FE(DSBCAPS_GLOBALFOCUS)
+ FE(DSBCAPS_GETCURRENTPOSITION2)
+ FE(DSBCAPS_MUTE3DATMAXDISTANCE)
+#undef FE
+ };
+ int i;
+
+ for (i=0;i<sizeof(flags)/sizeof(flags[0]);i++)
+ if ((flags[i].mask & xmask) == flags[i].mask)
+ DPRINTF("%s ",flags[i].name);
+}
+
+/*******************************************************************************
+ * IDirectSound
+ */
+
+static HRESULT WINAPI IDirectSoundImpl_SetCooperativeLevel(
+ LPDIRECTSOUND8 iface,HWND hwnd,DWORD level
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%08lx,%ld)\n",This,(DWORD)hwnd,level);
+
+ if (level==DSSCL_PRIORITY || level==DSSCL_EXCLUSIVE) {
+ FIXME("level=%s not fully supported\n",
+ level==DSSCL_PRIORITY ? "DSSCL_PRIORITY" : "DSSCL_EXCLUSIVE");
+ }
+
+ This->priolevel = level;
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_CreateSoundBuffer(
+ LPDIRECTSOUND8 iface,LPCDSBUFFERDESC dsbd,LPLPDIRECTSOUNDBUFFER8 ppdsb,LPUNKNOWN lpunk
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ LPWAVEFORMATEX wfex;
+ HRESULT hres = DS_OK;
+
+ TRACE("(%p,%p,%p,%p)\n",This,dsbd,ppdsb,lpunk);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsbd == NULL) {
+ WARN("invalid parameter: dsbd == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (TRACE_ON(dsound)) {
+ TRACE("(structsize=%ld)\n",dsbd->dwSize);
+ TRACE("(flags=0x%08lx:\n",dsbd->dwFlags);
+ _dump_DSBCAPS(dsbd->dwFlags);
+ DPRINTF(")\n");
+ TRACE("(bufferbytes=%ld)\n",dsbd->dwBufferBytes);
+ TRACE("(lpwfxFormat=%p)\n",dsbd->lpwfxFormat);
+ }
+
+ wfex = dsbd->lpwfxFormat;
+
+ if (wfex)
+ TRACE("(formattag=0x%04x,chans=%d,samplerate=%ld,"
+ "bytespersec=%ld,blockalign=%d,bitspersamp=%d,cbSize=%d)\n",
+ wfex->wFormatTag, wfex->nChannels, wfex->nSamplesPerSec,
+ wfex->nAvgBytesPerSec, wfex->nBlockAlign,
+ wfex->wBitsPerSample, wfex->cbSize);
+
+ if (dsbd->dwFlags & DSBCAPS_PRIMARYBUFFER) {
+ if (This->primary) {
+ WARN("Primary Buffer already created\n");
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+ *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
+ } else {
+ This->dsbd = *dsbd;
+ hres = PrimaryBufferImpl_Create(This, (PrimaryBufferImpl**)&(This->primary), &(This->dsbd));
+ if (This->primary) {
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)(This->primary));
+ *ppdsb = (LPDIRECTSOUNDBUFFER8)(This->primary);
+ } else
+ WARN("PrimaryBufferImpl_Create failed\n");
+ }
+ } else {
+ IDirectSoundBufferImpl * dsb;
+ hres = IDirectSoundBufferImpl_Create(This, (IDirectSoundBufferImpl**)&dsb, dsbd);
+ if (dsb) {
+ hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+ if (*ppdsb) {
+ dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+ } else
+ WARN("SecondaryBufferImpl_Create failed\n");
+ } else
+ WARN("IDirectSoundBufferImpl_Create failed\n");
+ }
+
+ return hres;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_DuplicateSoundBuffer(
+ LPDIRECTSOUND8 iface,LPDIRECTSOUNDBUFFER8 psb,LPLPDIRECTSOUNDBUFFER8 ppdsb
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ IDirectSoundBufferImpl* pdsb;
+ IDirectSoundBufferImpl* dsb;
+ HRESULT hres = DS_OK;
+ TRACE("(%p,%p,%p)\n",This,psb,ppdsb);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (psb == NULL) {
+ WARN("invalid parameter: psb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (ppdsb == NULL) {
+ WARN("invalid parameter: ppdsb == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* FIXME: hack to make sure we have a secondary buffer */
+ if ((DWORD)((SecondaryBufferImpl *)psb)->dsb == (DWORD)This) {
+ ERR("trying to duplicate primary buffer\n");
+ *ppdsb = NULL;
+ return DSERR_INVALIDCALL;
+ }
+
+ pdsb = ((SecondaryBufferImpl *)psb)->dsb;
+
+ dsb = (IDirectSoundBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsb));
+
+ if (dsb == NULL) {
+ WARN("out of memory\n");
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ memcpy(dsb, pdsb, sizeof(IDirectSoundBufferImpl));
+
+ if (pdsb->hwbuf) {
+ TRACE("duplicating hardware buffer\n");
+
+ hres = IDsDriver_DuplicateSoundBuffer(This->driver, pdsb->hwbuf, (LPVOID *)&dsb->hwbuf);
+ if (hres != DS_OK) {
+ TRACE("IDsDriver_DuplicateSoundBuffer failed, falling back to software buffer\n");
+ dsb->hwbuf = NULL;
+ /* allocate buffer */
+ if (This->drvdesc.dwFlags & DSDDESC_USESYSTEMMEMORY) {
+ dsb->buffer = HeapAlloc(GetProcessHeap(),0,sizeof(*(dsb->buffer)));
+ if (dsb->buffer == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ dsb->buffer->memory = (LPBYTE)HeapAlloc(GetProcessHeap(),0,dsb->buflen);
+ if (dsb->buffer->memory == NULL) {
+ WARN("out of memory\n");
+ HeapFree(GetProcessHeap(),0,dsb->buffer);
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = NULL;
+ return DSERR_OUTOFMEMORY;
+ }
+ dsb->buffer->ref = 1;
+
+ /* FIXME: copy buffer ? */
+ }
+ }
+ } else {
+ dsb->hwbuf = NULL;
+ dsb->buffer->ref++;
+ }
+
+ dsb->ref = 0;
+ dsb->state = STATE_STOPPED;
+ dsb->playpos = 0;
+ dsb->buf_mixpos = 0;
+ dsb->dsound = This;
+ dsb->ds3db = NULL;
+ dsb->iks = NULL; /* FIXME? */
+ dsb->dsb = NULL;
+ memcpy(&(dsb->wfx), &(pdsb->wfx), sizeof(dsb->wfx));
+ InitializeCriticalSection(&(dsb->lock));
+ /* register buffer */
+ RtlAcquireResourceExclusive(&(This->lock), TRUE);
+ {
+ IDirectSoundBufferImpl **newbuffers;
+ if (This->buffers)
+ newbuffers = (IDirectSoundBufferImpl**)HeapReAlloc(GetProcessHeap(),0,This->buffers,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
+ else
+ newbuffers = (IDirectSoundBufferImpl**)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectSoundBufferImpl**)*(This->nrofbuffers+1));
+
+ if (newbuffers) {
+ This->buffers = newbuffers;
+ This->buffers[This->nrofbuffers] = dsb;
+ This->nrofbuffers++;
+ TRACE("buffer count is now %d\n", This->nrofbuffers);
+ } else {
+ ERR("out of memory for buffer list! Current buffer count is %d\n", This->nrofbuffers);
+ IDirectSoundBuffer8_Release(psb);
+ DeleteCriticalSection(&(dsb->lock));
+ RtlReleaseResource(&(This->lock));
+ HeapFree(GetProcessHeap(),0,dsb);
+ *ppdsb = 0;
+ return DSERR_OUTOFMEMORY;
+ }
+ }
+ RtlReleaseResource(&(This->lock));
+ IDirectSound_AddRef(iface);
+ hres = SecondaryBufferImpl_Create(dsb, (SecondaryBufferImpl**)ppdsb);
+ if (*ppdsb) {
+ dsb->dsb = (SecondaryBufferImpl*)*ppdsb;
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)*ppdsb);
+ } else
+ WARN("SecondaryBufferImpl_Create failed\n");
+
+ return hres;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_GetCaps(LPDIRECTSOUND8 iface,LPDSCAPS lpDSCaps) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%p)\n",This,lpDSCaps);
+
+ if (This == NULL) {
+ WARN("invalid parameter: This == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (lpDSCaps == NULL) {
+ WARN("invalid parameter: lpDSCaps = NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* check is there is enough room */
+ if (lpDSCaps->dwSize < sizeof(*lpDSCaps)) {
+ WARN("invalid parameter: lpDSCaps->dwSize = %ld < %d\n",
+ lpDSCaps->dwSize, sizeof(*lpDSCaps));
+ return DSERR_INVALIDPARAM;
+ }
+
+ lpDSCaps->dwFlags = This->drvcaps.dwFlags;
+ TRACE("(flags=0x%08lx)\n",lpDSCaps->dwFlags);
+
+ lpDSCaps->dwMinSecondarySampleRate = This->drvcaps.dwMinSecondarySampleRate;
+ lpDSCaps->dwMaxSecondarySampleRate = This->drvcaps.dwMaxSecondarySampleRate;
+
+ lpDSCaps->dwPrimaryBuffers = This->drvcaps.dwPrimaryBuffers;
+
+ lpDSCaps->dwMaxHwMixingAllBuffers = This->drvcaps.dwMaxHwMixingAllBuffers;
+ lpDSCaps->dwMaxHwMixingStaticBuffers = This->drvcaps.dwMaxHwMixingStaticBuffers;
+ lpDSCaps->dwMaxHwMixingStreamingBuffers = This->drvcaps.dwMaxHwMixingStreamingBuffers;
+
+ lpDSCaps->dwFreeHwMixingAllBuffers = This->drvcaps.dwFreeHwMixingAllBuffers;
+ lpDSCaps->dwFreeHwMixingStaticBuffers = This->drvcaps.dwFreeHwMixingStaticBuffers;
+ lpDSCaps->dwFreeHwMixingStreamingBuffers = This->drvcaps.dwFreeHwMixingStreamingBuffers;
+
+ lpDSCaps->dwMaxHw3DAllBuffers = This->drvcaps.dwMaxHw3DAllBuffers;
+ lpDSCaps->dwMaxHw3DStaticBuffers = This->drvcaps.dwMaxHw3DStaticBuffers;
+ lpDSCaps->dwMaxHw3DStreamingBuffers = This->drvcaps.dwMaxHw3DStreamingBuffers;
+
+ lpDSCaps->dwFreeHw3DAllBuffers = This->drvcaps.dwFreeHw3DAllBuffers;
+ lpDSCaps->dwFreeHw3DStaticBuffers = This->drvcaps.dwFreeHw3DStaticBuffers;
+ lpDSCaps->dwFreeHw3DStreamingBuffers = This->drvcaps.dwFreeHw3DStreamingBuffers;
+
+ lpDSCaps->dwTotalHwMemBytes = This->drvcaps.dwTotalHwMemBytes;
+
+ lpDSCaps->dwFreeHwMemBytes = This->drvcaps.dwFreeHwMemBytes;
+
+ lpDSCaps->dwMaxContigFreeHwMemBytes = This->drvcaps.dwMaxContigFreeHwMemBytes;
+
+ /* driver doesn't have these */
+ lpDSCaps->dwUnlockTransferRateHwBuffers = 4096; /* But we have none... */
+
+ lpDSCaps->dwPlayCpuOverheadSwBuffers = 1; /* 1% */
+
+ return DS_OK;
+}
+
+static ULONG WINAPI IDirectSoundImpl_AddRef(LPDIRECTSOUND8 iface) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI IDirectSoundImpl_Release(LPDIRECTSOUND8 iface) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ ULONG ulReturn;
+
+ TRACE("(%p) ref was %ld, thread is %04lx\n", This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (ulReturn == 0) {
+ HRESULT hres;
+ UINT i;
+
+ timeKillEvent(This->timerID);
+ timeEndPeriod(DS_TIME_RES);
+ /* wait for timer to expire */
+ Sleep(DS_TIME_RES+1);
+
+ RtlAcquireResourceShared(&(This->lock), TRUE);
+
+ if (This->buffers) {
+ for( i=0;i<This->nrofbuffers;i++)
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->buffers[i]);
+ }
+
+ RtlReleaseResource(&(This->lock));
+
+ if (This->primary) {
+ WARN("primary buffer not released\n");
+ IDirectSoundBuffer8_Release((LPDIRECTSOUNDBUFFER8)This->primary);
+ }
+
+ hres = DSOUND_PrimaryDestroy(This);
+ if (hres != DS_OK)
+ WARN("DSOUND_PrimaryDestroy failed\n");
+
+ if (This->driver)
+ IDsDriver_Close(This->driver);
+
+ if (This->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ waveOutClose(This->hwo);
+
+ if (This->driver)
+ IDsDriver_Release(This->driver);
+
+ RtlDeleteResource(&This->lock);
+ DeleteCriticalSection(&This->mixlock);
+ HeapFree(GetProcessHeap(),0,This);
+ dsound = NULL;
+ TRACE("(%p) released\n",This);
+ }
+
+ return ulReturn;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_SetSpeakerConfig(
+ LPDIRECTSOUND8 iface,DWORD config
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,0x%08lx)\n",This,config);
+
+ This->speaker_config = config;
+
+ WARN("not fully functional\n");
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_QueryInterface(
+ LPDIRECTSOUND8 iface,REFIID riid,LPVOID *ppobj
+) {
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
+ }
+
+ *ppobj = NULL; /* assume failure */
+
+ if ( IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IDirectSound) ||
+ IsEqualGUID(riid, &IID_IDirectSound8) ) {
+ IDirectSound8_AddRef((LPDIRECTSOUND8)This);
+ *ppobj = This;
+ return S_OK;
+ }
+
+ if ( IsEqualGUID( &IID_IDirectSound3DListener, riid ) ) {
+ WARN("app requested IDirectSound3DListener on dsound object\n");
+ return E_NOINTERFACE;
+ }
+
+ FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_Compact(
+ LPDIRECTSOUND8 iface)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p)\n", This);
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_GetSpeakerConfig(
+ LPDIRECTSOUND8 iface,
+ LPDWORD lpdwSpeakerConfig)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %p)\n", This, lpdwSpeakerConfig);
+
+ if (lpdwSpeakerConfig == NULL) {
+ WARN("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ WARN("not fully functional\n");
+
+ *lpdwSpeakerConfig = This->speaker_config;
+
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_Initialize(
+ LPDIRECTSOUND8 iface,
+ LPCGUID lpcGuid)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %s)\n", This, debugstr_guid(lpcGuid));
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSoundImpl_VerifyCertification(
+ LPDIRECTSOUND8 iface,
+ LPDWORD pdwCertified)
+{
+ ICOM_THIS(IDirectSoundImpl,iface);
+ TRACE("(%p, %p)\n", This, pdwCertified);
+ *pdwCertified = DS_CERTIFIED;
+ return DS_OK;
+}
+
+static ICOM_VTABLE(IDirectSound8) dsvt =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IDirectSoundImpl_QueryInterface,
+ IDirectSoundImpl_AddRef,
+ IDirectSoundImpl_Release,
+ IDirectSoundImpl_CreateSoundBuffer,
+ IDirectSoundImpl_GetCaps,
+ IDirectSoundImpl_DuplicateSoundBuffer,
+ IDirectSoundImpl_SetCooperativeLevel,
+ IDirectSoundImpl_Compact,
+ IDirectSoundImpl_GetSpeakerConfig,
+ IDirectSoundImpl_SetSpeakerConfig,
+ IDirectSoundImpl_Initialize,
+ IDirectSoundImpl_VerifyCertification
+};
+
+
+/*******************************************************************************
+ * DirectSoundCreate (DSOUND.1)
+ *
+ * Creates and initializes a DirectSound interface.
+ *
+ * PARAMS
+ * lpcGUID [I] Address of the GUID that identifies the sound device.
+ * ppDS [O] Address of a variable to receive the interface pointer.
+ * pUnkOuter [I] Must be NULL.
+ *
+ * RETURNS
+ * Success: DS_OK
+ * Failure: DSERR_ALLOCATED, DSERR_INVALIDPARAM, DSERR_NOAGGREGATION,
+ * DSERR_NODRIVER, DSERR_OUTOFMEMORY
+ */
+HRESULT WINAPI DirectSoundCreate8(LPCGUID lpcGUID,LPDIRECTSOUND8 *ppDS,IUnknown *pUnkOuter )
+{
+ IDirectSoundImpl** ippDS=(IDirectSoundImpl**)ppDS;
+ PIDSDRIVER drv = NULL;
+ unsigned wod, wodn;
+ HRESULT err = DSERR_INVALIDPARAM;
+ GUID devGuid;
+ BOOLEAN found = FALSE;
+
+ TRACE("(%s,%p,%p)\n",debugstr_guid(lpcGUID),ippDS,pUnkOuter);
+
+ if (ippDS == NULL) {
+ WARN("invalid parameter: ippDS == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* Get dsound configuration */
+ setup_dsound_options();
+
+ /* Default device? */
+ if (!lpcGUID || IsEqualGUID(lpcGUID, &GUID_NULL))
+ lpcGUID = &DSDEVID_DefaultPlayback;
+
+ if (GetDeviceID(lpcGUID, &devGuid) != DS_OK) {
+ WARN("invalid parameter: lpcGUID\n");
+ *ippDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (dsound) {
+ if (IsEqualGUID(&devGuid, &dsound->guid) ) {
+ /* FIXME: this is wrong, need to create a new instance */
+ ERR("dsound already opened\n");
+ IDirectSound_AddRef((LPDIRECTSOUND)dsound);
+ *ippDS = dsound;
+ return DS_OK;
+ } else {
+ ERR("different dsound already opened\n");
+ }
+ }
+
+ /* Enumerate WINMM audio devices and find the one we want */
+ wodn = waveOutGetNumDevs();
+ if (!wodn) {
+ WARN("no driver\n");
+ *ippDS = NULL;
+ return DSERR_NODRIVER;
+ }
+
+ TRACE(" expecting GUID %s.\n", debugstr_guid(&devGuid));
+
+ for (wod=0; wod<wodn; wod++) {
+ GUID guid;
+ err = mmErr(waveOutMessage((HWAVEOUT)wod,DRV_QUERYDSOUNDGUID,(DWORD)(&guid),0));
+ if (err != DS_OK) {
+ WARN("waveOutMessage failed; err=%lx\n",err);
+ *ippDS = NULL;
+ return err;
+ }
+ TRACE("got GUID %s for wod %d.\n", debugstr_guid(&guid), wod);
+ if (IsEqualGUID( &devGuid, &guid) ) {
+ err = DS_OK;
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (err != DS_OK) {
+ WARN("invalid parameter\n");
+ *ippDS = NULL;
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (found == FALSE) {
+ WARN("No device found matching given ID - trying with default one !\n");
+ wod = ds_default_playback;
+ }
+
+ /* DRV_QUERYDSOUNDIFACE is a "Wine extension" to get the DSound interface */
+ waveOutMessage((HWAVEOUT)wod, DRV_QUERYDSOUNDIFACE, (DWORD)&drv, 0);
+
+ /* Disable the direct sound driver to force emulation if requested. */
+ if (ds_hw_accel == DS_HW_ACCEL_EMULATION)
+ drv = NULL;
+
+ /* Allocate memory */
+ *ippDS = (IDirectSoundImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDirectSoundImpl));
+ if (*ippDS == NULL) {
+ WARN("out of memory\n");
+ return DSERR_OUTOFMEMORY;
+ }
+
+ (*ippDS)->lpVtbl = &dsvt;
+ (*ippDS)->ref = 1;
+
+ (*ippDS)->driver = drv;
+ (*ippDS)->priolevel = DSSCL_NORMAL;
+ (*ippDS)->fraglen = 0;
+ (*ippDS)->hwbuf = NULL;
+ (*ippDS)->buffer = NULL;
+ (*ippDS)->buflen = 0;
+ (*ippDS)->writelead = 0;
+ (*ippDS)->state = STATE_STOPPED;
+ (*ippDS)->nrofbuffers = 0;
+ (*ippDS)->buffers = NULL;
+ (*ippDS)->primary = NULL;
+ (*ippDS)->speaker_config = DSSPEAKER_STEREO | (DSSPEAKER_GEOMETRY_NARROW << 16);
+
+ /* 3D listener initial parameters */
+ (*ippDS)->listener = NULL;
+ (*ippDS)->ds3dl.dwSize = sizeof(DS3DLISTENER);
+ (*ippDS)->ds3dl.vPosition.x = 0.0;
+ (*ippDS)->ds3dl.vPosition.y = 0.0;
+ (*ippDS)->ds3dl.vPosition.z = 0.0;
+ (*ippDS)->ds3dl.vVelocity.x = 0.0;
+ (*ippDS)->ds3dl.vVelocity.y = 0.0;
+ (*ippDS)->ds3dl.vVelocity.z = 0.0;
+ (*ippDS)->ds3dl.vOrientFront.x = 0.0;
+ (*ippDS)->ds3dl.vOrientFront.y = 0.0;
+ (*ippDS)->ds3dl.vOrientFront.z = 1.0;
+ (*ippDS)->ds3dl.vOrientTop.x = 0.0;
+ (*ippDS)->ds3dl.vOrientTop.y = 1.0;
+ (*ippDS)->ds3dl.vOrientTop.z = 0.0;
+ (*ippDS)->ds3dl.flDistanceFactor = DS3D_DEFAULTDISTANCEFACTOR;
+ (*ippDS)->ds3dl.flRolloffFactor = DS3D_DEFAULTROLLOFFFACTOR;
+ (*ippDS)->ds3dl.flDopplerFactor = DS3D_DEFAULTDOPPLERFACTOR;
+
+ (*ippDS)->prebuf = ds_snd_queue_max;
+ (*ippDS)->guid = devGuid;
+
+ /* Get driver description */
+ if (drv) {
+ err = IDsDriver_GetDriverDesc(drv,&((*ippDS)->drvdesc));
+ if (err != DS_OK) {
+ WARN("IDsDriver_GetDriverDesc failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ } else {
+ /* if no DirectSound interface available, use WINMM API instead */
+ (*ippDS)->drvdesc.dwFlags = DSDDESC_DOMMSYSTEMOPEN | DSDDESC_DOMMSYSTEMSETFORMAT;
+ }
+
+ (*ippDS)->drvdesc.dnDevNode = wod;
+
+ /* Set default wave format (may need it for waveOutOpen) */
+ (*ippDS)->wfx.wFormatTag = WAVE_FORMAT_PCM;
+ /* We rely on the sound driver to return the actual sound format of
+ * the device if it does not support 22050x8x2 and is given the
+ * WAVE_DIRECTSOUND flag.
+ */
+ (*ippDS)->wfx.nSamplesPerSec = 22050;
+ (*ippDS)->wfx.wBitsPerSample = 8;
+ (*ippDS)->wfx.nChannels = 2;
+ (*ippDS)->wfx.nBlockAlign = (*ippDS)->wfx.wBitsPerSample * (*ippDS)->wfx.nChannels / 8;
+ (*ippDS)->wfx.nAvgBytesPerSec = (*ippDS)->wfx.nSamplesPerSec * (*ippDS)->wfx.nBlockAlign;
+ (*ippDS)->wfx.cbSize = 0;
+
+ /* If the driver requests being opened through MMSYSTEM
+ * (which is recommended by the DDK), it is supposed to happen
+ * before the DirectSound interface is opened */
+ if ((*ippDS)->drvdesc.dwFlags & DSDDESC_DOMMSYSTEMOPEN)
+ {
+ DWORD flags = CALLBACK_FUNCTION;
+
+ /* disable direct sound if requested */
+ if (ds_hw_accel != DS_HW_ACCEL_EMULATION)
+ flags |= WAVE_DIRECTSOUND;
+
+ err = mmErr(waveOutOpen(&((*ippDS)->hwo),
+ (*ippDS)->drvdesc.dnDevNode, &((*ippDS)->wfx),
+ (DWORD)DSOUND_callback, (DWORD)(*ippDS),
+ flags));
+ if (err != DS_OK) {
+ WARN("waveOutOpen failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ }
+
+ if (drv) {
+ err = IDsDriver_Open(drv);
+ if (err != DS_OK) {
+ WARN("IDsDriver_Open failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+
+ /* the driver is now open, so it's now allowed to call GetCaps */
+ err = IDsDriver_GetCaps(drv,&((*ippDS)->drvcaps));
+ if (err != DS_OK) {
+ WARN("IDsDriver_GetCaps failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ } else {
+ WAVEOUTCAPSA woc;
+ err = mmErr(waveOutGetDevCapsA((*ippDS)->drvdesc.dnDevNode, &woc, sizeof(woc)));
+ if (err != DS_OK) {
+ WARN("waveOutGetDevCaps failed\n");
+ HeapFree(GetProcessHeap(),0,*ippDS);
+ *ippDS = NULL;
+ return err;
+ }
+ ZeroMemory(&(*ippDS)->drvcaps, sizeof((*ippDS)->drvcaps));
+ if ((woc.dwFormats & WAVE_FORMAT_1M08) ||
+ (woc.dwFormats & WAVE_FORMAT_2M08) ||
+ (woc.dwFormats & WAVE_FORMAT_4M08) ||
+ (woc.dwFormats & WAVE_FORMAT_48M08) ||
+ (woc.dwFormats & WAVE_FORMAT_96M08)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1M16) ||
+ (woc.dwFormats & WAVE_FORMAT_2M16) ||
+ (woc.dwFormats & WAVE_FORMAT_4M16) ||
+ (woc.dwFormats & WAVE_FORMAT_48M16) ||
+ (woc.dwFormats & WAVE_FORMAT_96M16)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYMONO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1S08) ||
+ (woc.dwFormats & WAVE_FORMAT_2S08) ||
+ (woc.dwFormats & WAVE_FORMAT_4S08) ||
+ (woc.dwFormats & WAVE_FORMAT_48S08) ||
+ (woc.dwFormats & WAVE_FORMAT_96S08)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY8BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
+ }
+ if ((woc.dwFormats & WAVE_FORMAT_1S16) ||
+ (woc.dwFormats & WAVE_FORMAT_2S16) ||
+ (woc.dwFormats & WAVE_FORMAT_4S16) ||
+ (woc.dwFormats & WAVE_FORMAT_48S16) ||
+ (woc.dwFormats & WAVE_FORMAT_96S16)) {
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARY16BIT;
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_PRIMARYSTEREO;
+ }
+ if (ds_emuldriver)
+ (*ippDS)->drvcaps.dwFlags |= DSCAPS_EMULDRIVER;
+ (*ippDS)->drvcaps.dwMinSecondarySampleRate = DSBFREQUENCY_MIN;
+ (*ippDS)->drvcaps.dwMaxSecondarySampleRate = DSBFREQUENCY_MAX;
+ (*ippDS)->drvcaps.dwPrimaryBuffers = 1;
+ }
+
+ (*ippDS)->volpan.lVolume = 0;
+ (*ippDS)->volpan.lPan = 0;
+ DSOUND_RecalcVolPan(&((*ippDS)->volpan));
+
+ InitializeCriticalSection(&((*ippDS)->mixlock));
+ RtlInitializeResource(&((*ippDS)->lock));
+
+ if (!dsound) {
+ HRESULT hres;
+ dsound = (*ippDS);
+ hres = DSOUND_PrimaryCreate(dsound);
+ if (hres != DS_OK) {
+ WARN("DSOUND_PrimaryCreate failed\n");
+ return hres;
+ }
+ timeBeginPeriod(DS_TIME_RES);
+ dsound->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, DSOUND_timer,
+ (DWORD)dsound, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
+ }
+
+ return DS_OK;
+}
+
+
+/*******************************************************************************
+ * DirectSound ClassFactory
+ */
+
+static HRESULT WINAPI
+DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+
+ FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+DSCF_AddRef(LPCLASSFACTORY iface) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ TRACE("(%p) ref was %ld\n", This, This->ref);
+ return ++(This->ref);
+}
+
+static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ /* static class, won't be freed */
+ TRACE("(%p) ref was %ld\n", This, This->ref);
+ return --(This->ref);
+}
+
+static HRESULT WINAPI DSCF_CreateInstance(
+ LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ *ppobj = NULL;
+
+ if ( IsEqualGUID( &IID_IDirectSound, riid ) ||
+ IsEqualGUID( &IID_IDirectSound8, riid ) ) {
+ /* FIXME: reuse already created dsound if present? */
+ return DirectSoundCreate8(0,(LPDIRECTSOUND8*)ppobj,pOuter);
+ }
+
+ WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ FIXME("(%p)->(%d),stub!\n",This,dolock);
+ return S_OK;
+}
+
+static ICOM_VTABLE(IClassFactory) DSCF_Vtbl = {
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ DSCF_QueryInterface,
+ DSCF_AddRef,
+ DSCF_Release,
+ DSCF_CreateInstance,
+ DSCF_LockServer
+};
+
+static IClassFactoryImpl DSOUND_CF = { &DSCF_Vtbl, 1 };
+
+/*******************************************************************************
+ * DirectSoundPrivate ClassFactory
+ */
+
+static HRESULT WINAPI
+DSPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+
+ FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI
+DSPCF_AddRef(LPCLASSFACTORY iface) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ TRACE("(%p) ref was %ld\n", This, This->ref);
+ return ++(This->ref);
+}
+
+static ULONG WINAPI
+DSPCF_Release(LPCLASSFACTORY iface) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ /* static class, won't be freed */
+ TRACE("(%p) ref was %ld\n", This, This->ref);
+ return --(This->ref);
+}
+
+static HRESULT WINAPI
+DSPCF_CreateInstance(
+ LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ *ppobj = NULL;
+
+ if ( IsEqualGUID( &IID_IKsPropertySet, riid ) ) {
+ return IKsPrivatePropertySetImpl_Create((IKsPrivatePropertySetImpl**)ppobj);
+ }
+
+ WARN("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI
+DSPCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+ ICOM_THIS(IClassFactoryImpl,iface);
+ FIXME("(%p)->(%d),stub!\n",This,dolock);
+ return S_OK;
+}
+
+static ICOM_VTABLE(IClassFactory) DSPCF_Vtbl = {
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ DSPCF_QueryInterface,
+ DSPCF_AddRef,
+ DSPCF_Release,
+ DSPCF_CreateInstance,
+ DSPCF_LockServer
+};
+
+static IClassFactoryImpl DSOUND_PRIVATE_CF = { &DSPCF_Vtbl, 1 };
+
+/*******************************************************************************
+ * DllGetClassObject [DSOUND.5]
+ * Retrieves class object from a DLL object
+ *
+ * NOTES
+ * Docs say returns STDAPI
+ *
+ * PARAMS
+ * rclsid [I] CLSID for the class object
+ * riid [I] Reference to identifier of interface for class object
+ * ppv [O] Address of variable to receive interface pointer for riid
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
+ * E_UNEXPECTED
+ */
+DWORD WINAPI DSOUND_DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID *ppv)
+{
+ TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+
+ if (ppv == NULL) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
+ }
+
+ *ppv = NULL;
+
+ if ( IsEqualCLSID( &CLSID_DirectSound, rclsid ) ||
+ IsEqualCLSID( &CLSID_DirectSound8, rclsid ) ) {
+ if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
+ *ppv = (LPVOID)&DSOUND_CF;
+ IClassFactory_AddRef((IClassFactory*)*ppv);
+ return S_OK;
+ }
+ WARN("(%s,%s,%p): no interface found.\n",
+ debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return S_FALSE;
+ }
+
+ if ( IsEqualCLSID( &CLSID_DirectSoundCapture, rclsid ) ||
+ IsEqualCLSID( &CLSID_DirectSoundCapture8, rclsid ) ) {
+ if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
+ *ppv = (LPVOID)&DSOUND_CAPTURE_CF;
+ IClassFactory_AddRef((IClassFactory*)*ppv);
+ return S_OK;
+ }
+ WARN("(%s,%s,%p): no interface found.\n",
+ debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return S_FALSE;
+ }
+
+ if ( IsEqualCLSID( &CLSID_DirectSoundFullDuplex, rclsid ) ) {
+ if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
+ *ppv = (LPVOID)&DSOUND_FULLDUPLEX_CF;
+ IClassFactory_AddRef((IClassFactory*)*ppv);
+ return S_OK;
+ }
+ WARN("(%s,%s,%p): no interface found.\n",
+ debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return S_FALSE;
+ }
+
+ if ( IsEqualCLSID( &CLSID_DirectSoundPrivate, rclsid ) ) {
+ if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
+ *ppv = (LPVOID)&DSOUND_PRIVATE_CF;
+ IClassFactory_AddRef((IClassFactory*)*ppv);
+ return S_OK;
+ }
+ WARN("(%s,%s,%p): no interface found.\n",
+ debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return S_FALSE;
+ }
+
+ WARN("(%s,%s,%p): no class found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+
+/*******************************************************************************
+ * DllCanUnloadNow [DSOUND.4]
+ * Determines whether the DLL is in use.
+ *
+ * RETURNS
+ * Success: S_OK
+ * Failure: S_FALSE
+ */
+DWORD WINAPI DSOUND_DllCanUnloadNow(void)
+{
+ FIXME("(void): stub\n");
+ return S_FALSE;
+}
Binary files dlls/dsound/dsound_main.o and /home/wine/wine.save6/dlls/dsound/dsound_main.o differ
Only in dlls/dsound: dsound.o
diff -u --unidirectional-new-file dlls/dsound/dsound_private.h /home/wine/wine.save6/dlls/dsound/dsound_private.h
--- dlls/dsound/dsound_private.h 2004-06-30 19:37:20.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/dsound_private.h 2004-03-16 21:16:30.000000000 -0500
@@ -44,25 +44,20 @@
/*****************************************************************************
* Predeclare the interface implementation structures
*/
-typedef struct IDirectSoundImpl IDirectSoundImpl;
-typedef struct IDirectSound_IUnknown IDirectSound_IUnknown;
-typedef struct IDirectSound_IDirectSound IDirectSound_IDirectSound;
-typedef struct IDirectSound8_IUnknown IDirectSound8_IUnknown;
-typedef struct IDirectSound8_IDirectSound IDirectSound8_IDirectSound;
-typedef struct IDirectSound8_IDirectSound8 IDirectSound8_IDirectSound8;
-typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
-typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
+typedef struct IDirectSoundImpl IDirectSoundImpl;
+typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
+typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
-typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
-typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
+typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
+typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
-typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
-typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
-typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
-typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
-typedef struct PrimaryBufferImpl PrimaryBufferImpl;
-typedef struct SecondaryBufferImpl SecondaryBufferImpl;
-typedef struct IClassFactoryImpl IClassFactoryImpl;
+typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
+typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
+typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
+typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
+typedef struct PrimaryBufferImpl PrimaryBufferImpl;
+typedef struct SecondaryBufferImpl SecondaryBufferImpl;
+typedef struct IClassFactoryImpl IClassFactoryImpl;
/*****************************************************************************
* IDirectSound implementation structure
@@ -100,10 +95,6 @@
IDirectSound3DListenerImpl* listener;
DS3DLISTENER ds3dl;
BOOL ds3dl_need_recalc;
-
- LPUNKNOWN pUnknown;
- LPDIRECTSOUND pDS;
- LPDIRECTSOUND8 pDS8;
};
/* reference counted buffer memory for duplicated buffer memory */
@@ -113,66 +104,6 @@
LPBYTE memory;
} BufferMemory;
-HRESULT WINAPI IDirectSoundImpl_Create(
- LPCGUID lpcGUID,
- LPDIRECTSOUND8 * ppds);
-
-/*****************************************************************************
- * IDirectSound COM components
- */
-struct IDirectSound_IUnknown {
- ICOM_VFIELD(IUnknown);
- DWORD ref;
- LPDIRECTSOUND8 pds;
-};
-
-HRESULT WINAPI IDirectSound_IUnknown_Create(
- LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk);
-
-struct IDirectSound_IDirectSound {
- ICOM_VFIELD(IDirectSound);
- DWORD ref;
- LPDIRECTSOUND8 pds;
-};
-
-HRESULT WINAPI IDirectSound_IDirectSound_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND * ppds);
-
-/*****************************************************************************
- * IDirectSound8 COM components
- */
-struct IDirectSound8_IUnknown {
- ICOM_VFIELD(IUnknown);
- DWORD ref;
- LPDIRECTSOUND8 pds;
-};
-
-HRESULT WINAPI IDirectSound8_IUnknown_Create(
- LPDIRECTSOUND8 pds,
- LPUNKNOWN * ppunk);
-
-struct IDirectSound8_IDirectSound {
- ICOM_VFIELD(IDirectSound);
- DWORD ref;
- LPDIRECTSOUND8 pds;
-};
-
-HRESULT WINAPI IDirectSound8_IDirectSound_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND * ppds);
-
-struct IDirectSound8_IDirectSound8 {
- ICOM_VFIELD(IDirectSound8);
- DWORD ref;
- LPDIRECTSOUND8 pds;
-};
-
-HRESULT WINAPI IDirectSound8_IDirectSound8_Create(
- LPDIRECTSOUND8 pds,
- LPDIRECTSOUND8 * ppds);
-
/*****************************************************************************
* IDirectSoundBuffer implementation structure
*/
diff -u --unidirectional-new-file dlls/dsound/.#dsound_private.h.1.14 /home/wine/wine.save6/dlls/dsound/.#dsound_private.h.1.14
--- dlls/dsound/.#dsound_private.h.1.14 1969-12-31 19:00:00.000000000 -0500
+++ /home/wine/wine.save6/dlls/dsound/.#dsound_private.h.1.14 2004-03-16 19:25:24.000000000 -0500
@@ -0,0 +1,403 @@
+/* DirectSound
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998 Rob Riggs
+ * Copyright 2000-2001 TransGaming Technologies, Inc.
+ *
+ * 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
+ */
+
+/* Linux does not support better timing than 10ms */
+#define DS_TIME_RES 10 /* Resolution of multimedia timer */
+#define DS_TIME_DEL 10 /* Delay of multimedia timer callback, and duration of HEL fragment */
+
+#define DS_HEL_FRAGS 48 /* HEL only: number of waveOut fragments in primary buffer
+ * (changing this won't help you) */
+
+/* direct sound hardware acceleration levels */
+#define DS_HW_ACCEL_FULL 0 /* default on Windows 98 */
+#define DS_HW_ACCEL_STANDARD 1 /* default on Windows 2000 */
+#define DS_HW_ACCEL_BASIC 2
+#define DS_HW_ACCEL_EMULATION 3
+
+extern int ds_emuldriver;
+extern int ds_hel_margin;
+extern int ds_hel_queue;
+extern int ds_snd_queue_max;
+extern int ds_snd_queue_min;
+extern int ds_hw_accel;
+extern int ds_default_playback;
+extern int ds_default_capture;
+
+/*****************************************************************************
+ * Predeclare the interface implementation structures
+ */
+typedef struct IDirectSoundImpl IDirectSoundImpl;
+typedef struct IDirectSoundBufferImpl IDirectSoundBufferImpl;
+typedef struct IDirectSoundCaptureImpl IDirectSoundCaptureImpl;
+typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
+typedef struct IDirectSoundFullDuplexImpl IDirectSoundFullDuplexImpl;
+typedef struct IDirectSoundNotifyImpl IDirectSoundNotifyImpl;
+typedef struct IDirectSoundCaptureNotifyImpl IDirectSoundCaptureNotifyImpl;
+typedef struct IDirectSound3DListenerImpl IDirectSound3DListenerImpl;
+typedef struct IDirectSound3DBufferImpl IDirectSound3DBufferImpl;
+typedef struct IKsBufferPropertySetImpl IKsBufferPropertySetImpl;
+typedef struct IKsPrivatePropertySetImpl IKsPrivatePropertySetImpl;
+typedef struct PrimaryBufferImpl PrimaryBufferImpl;
+typedef struct SecondaryBufferImpl SecondaryBufferImpl;
+typedef struct IClassFactoryImpl IClassFactoryImpl;
+
+/*****************************************************************************
+ * IDirectSound implementation structure
+ */
+struct IDirectSoundImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSound8);
+ DWORD ref;
+ /* IDirectSoundImpl fields */
+ GUID guid;
+ PIDSDRIVER driver;
+ DSDRIVERDESC drvdesc;
+ DSDRIVERCAPS drvcaps;
+ DWORD priolevel;
+ WAVEFORMATEX wfx; /* current main waveformat */
+ HWAVEOUT hwo;
+ LPWAVEHDR pwave[DS_HEL_FRAGS];
+ UINT timerID, pwplay, pwwrite, pwqueue, prebuf, precount;
+ DWORD fraglen;
+ PIDSDRIVERBUFFER hwbuf;
+ LPBYTE buffer;
+ DWORD writelead, buflen, state, playpos, mixpos;
+ BOOL need_remix;
+ int nrofbuffers;
+ IDirectSoundBufferImpl** buffers;
+ RTL_RWLOCK lock;
+ CRITICAL_SECTION mixlock;
+ DSVOLUMEPAN volpan;
+ PrimaryBufferImpl* primary;
+ DSBUFFERDESC dsbd;
+ DWORD speaker_config;
+
+ /* DirectSound3DListener fields */
+ IDirectSound3DListenerImpl* listener;
+ DS3DLISTENER ds3dl;
+ BOOL ds3dl_need_recalc;
+};
+
+/* reference counted buffer memory for duplicated buffer memory */
+typedef struct BufferMemory
+{
+ DWORD ref;
+ LPBYTE memory;
+} BufferMemory;
+
+/*****************************************************************************
+ * IDirectSoundBuffer implementation structure
+ */
+struct IDirectSoundBufferImpl
+{
+ /* FIXME: document */
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSoundBuffer8);
+ DWORD ref;
+ /* IDirectSoundBufferImpl fields */
+ SecondaryBufferImpl* dsb;
+ IDirectSoundImpl* dsound;
+ CRITICAL_SECTION lock;
+ PIDSDRIVERBUFFER hwbuf;
+ WAVEFORMATEX wfx;
+ BufferMemory* buffer;
+ DWORD playflags,state,leadin;
+ DWORD playpos,startpos,writelead,buflen;
+ DWORD nAvgBytesPerSec;
+ DWORD freq;
+ DSVOLUMEPAN volpan, cvolpan;
+ DSBUFFERDESC dsbd;
+ /* used for frequency conversion (PerfectPitch) */
+ ULONG freqAdjust, freqAcc;
+ /* used for intelligent (well, sort of) prebuffering */
+ DWORD probably_valid_to, last_playpos;
+ DWORD primary_mixpos, buf_mixpos;
+ BOOL need_remix;
+
+ /* IDirectSoundNotifyImpl fields */
+ IDirectSoundNotifyImpl* notify;
+ LPDSBPOSITIONNOTIFY notifies;
+ int nrofnotifies;
+ PIDSDRIVERNOTIFY hwnotify;
+
+ /* DirectSound3DBuffer fields */
+ IDirectSound3DBufferImpl* ds3db;
+ DS3DBUFFER ds3db_ds3db;
+ LONG ds3db_lVolume;
+ BOOL ds3db_need_recalc;
+
+ /* IKsPropertySet fields */
+ IKsBufferPropertySetImpl* iks;
+};
+
+HRESULT WINAPI IDirectSoundBufferImpl_Create(
+ IDirectSoundImpl *ds,
+ IDirectSoundBufferImpl **pdsb,
+ LPCDSBUFFERDESC dsbd);
+
+/*****************************************************************************
+ * SecondaryBuffer implementation structure
+ */
+struct SecondaryBufferImpl
+{
+ ICOM_VFIELD(IDirectSoundBuffer8);
+ DWORD ref;
+ IDirectSoundBufferImpl* dsb;
+};
+
+HRESULT WINAPI SecondaryBufferImpl_Create(
+ IDirectSoundBufferImpl *dsb,
+ SecondaryBufferImpl **pdsb);
+
+/*****************************************************************************
+ * PrimaryBuffer implementation structure
+ */
+struct PrimaryBufferImpl
+{
+ ICOM_VFIELD(IDirectSoundBuffer8);
+ DWORD ref;
+ IDirectSoundImpl* dsound;
+};
+
+HRESULT WINAPI PrimaryBufferImpl_Create(
+ IDirectSoundImpl *ds,
+ PrimaryBufferImpl **pdsb,
+ LPCDSBUFFERDESC dsbd);
+
+/*****************************************************************************
+ * IDirectSoundCapture implementation structure
+ */
+struct IDirectSoundCaptureImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSoundCapture);
+ DWORD ref;
+
+ /* IDirectSoundCaptureImpl fields */
+ GUID guid;
+ BOOL initialized;
+
+ /* DirectSound driver stuff */
+ PIDSCDRIVER driver;
+ DSDRIVERDESC drvdesc;
+ DSCDRIVERCAPS drvcaps;
+ PIDSCDRIVERBUFFER hwbuf;
+
+ /* wave driver info */
+ HWAVEIN hwi;
+
+ /* more stuff */
+ LPBYTE buffer;
+ DWORD buflen;
+ DWORD read_position;
+
+ PWAVEFORMATEX pwfx;
+
+ IDirectSoundCaptureBufferImpl* capture_buffer;
+ DWORD state;
+ LPWAVEHDR pwave;
+ int nrofpwaves;
+ int index;
+ CRITICAL_SECTION lock;
+};
+
+/*****************************************************************************
+ * IDirectSoundCaptureBuffer implementation structure
+ */
+struct IDirectSoundCaptureBufferImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSoundCaptureBuffer8);
+ DWORD ref;
+
+ /* IDirectSoundCaptureBufferImpl fields */
+ IDirectSoundCaptureImpl* dsound;
+ /* FIXME: don't need this */
+ LPDSCBUFFERDESC pdscbd;
+ DWORD flags;
+
+ /* IDirectSoundCaptureNotifyImpl fields */
+ IDirectSoundCaptureNotifyImpl* notify;
+ LPDSBPOSITIONNOTIFY notifies;
+ int nrofnotifies;
+ PIDSDRIVERNOTIFY hwnotify;
+};
+
+/*****************************************************************************
+ * IDirectSoundFullDuplex implementation structure
+ */
+struct IDirectSoundFullDuplexImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSoundFullDuplex);
+ DWORD ref;
+
+ /* IDirectSoundFullDuplexImpl fields */
+ CRITICAL_SECTION lock;
+};
+
+/*****************************************************************************
+ * IDirectSoundNotify implementation structure
+ */
+struct IDirectSoundNotifyImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSoundNotify);
+ DWORD ref;
+ IDirectSoundBufferImpl* dsb;
+};
+
+HRESULT WINAPI IDirectSoundNotifyImpl_Create(
+ IDirectSoundBufferImpl *dsb,
+ IDirectSoundNotifyImpl **pdsn);
+
+/*****************************************************************************
+ * IDirectSoundCaptureNotify implementation structure
+ */
+struct IDirectSoundCaptureNotifyImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSoundNotify);
+ DWORD ref;
+ IDirectSoundCaptureBufferImpl* dscb;
+};
+
+HRESULT WINAPI IDirectSoundCaptureNotifyImpl_Create(
+ IDirectSoundCaptureBufferImpl *dscb,
+ IDirectSoundCaptureNotifyImpl ** pdscn);
+
+/*****************************************************************************
+ * IDirectSound3DListener implementation structure
+ */
+struct IDirectSound3DListenerImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSound3DListener);
+ DWORD ref;
+ /* IDirectSound3DListenerImpl fields */
+ IDirectSoundImpl* dsound;
+};
+
+HRESULT WINAPI IDirectSound3DListenerImpl_Create(
+ PrimaryBufferImpl *pb,
+ IDirectSound3DListenerImpl **pdsl);
+
+/*****************************************************************************
+ * IKsBufferPropertySet implementation structure
+ */
+struct IKsBufferPropertySetImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IKsPropertySet);
+ DWORD ref;
+ /* IKsPropertySetImpl fields */
+ IDirectSoundBufferImpl* dsb;
+};
+
+HRESULT WINAPI IKsBufferPropertySetImpl_Create(
+ IDirectSoundBufferImpl *dsb,
+ IKsBufferPropertySetImpl **piks);
+
+/*****************************************************************************
+ * IKsPrivatePropertySet implementation structure
+ */
+struct IKsPrivatePropertySetImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IKsPropertySet);
+ DWORD ref;
+};
+
+HRESULT WINAPI IKsPrivatePropertySetImpl_Create(
+ IKsPrivatePropertySetImpl **piks);
+
+/*****************************************************************************
+ * IDirectSound3DBuffer implementation structure
+ */
+struct IDirectSound3DBufferImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IDirectSound3DBuffer);
+ DWORD ref;
+ /* IDirectSound3DBufferImpl fields */
+ IDirectSoundBufferImpl* dsb;
+};
+
+HRESULT WINAPI IDirectSound3DBufferImpl_Create(
+ IDirectSoundBufferImpl *dsb,
+ IDirectSound3DBufferImpl **pds3db);
+
+/*******************************************************************************
+ * DirectSound ClassFactory implementation structure
+ */
+struct IClassFactoryImpl
+{
+ /* IUnknown fields */
+ ICOM_VFIELD(IClassFactory);
+ DWORD ref;
+};
+
+extern IClassFactoryImpl DSOUND_CAPTURE_CF;
+extern IClassFactoryImpl DSOUND_FULLDUPLEX_CF;
+
+void DSOUND_RecalcVolPan(PDSVOLUMEPAN volpan);
+void DSOUND_RecalcFormat(IDirectSoundBufferImpl *dsb);
+
+/* primary.c */
+
+HRESULT DSOUND_PrimaryCreate(IDirectSoundImpl *This);
+HRESULT DSOUND_PrimaryDestroy(IDirectSoundImpl *This);
+HRESULT DSOUND_PrimaryPlay(IDirectSoundImpl *This);
+HRESULT DSOUND_PrimaryStop(IDirectSoundImpl *This);
+HRESULT DSOUND_PrimaryGetPosition(IDirectSoundImpl *This, LPDWORD playpos, LPDWORD writepos);
+
+/* buffer.c */
+
+DWORD DSOUND_CalcPlayPosition(IDirectSoundBufferImpl *This,
+ DWORD state, DWORD pplay, DWORD pwrite, DWORD pmix, DWORD bmix);
+
+/* mixer.c */
+
+void DSOUND_CheckEvent(IDirectSoundBufferImpl *dsb, int len);
+void DSOUND_ForceRemix(IDirectSoundBufferImpl *dsb);
+void DSOUND_MixCancelAt(IDirectSoundBufferImpl *dsb, DWORD buf_writepos);
+void DSOUND_WaveQueue(IDirectSoundImpl *dsound, DWORD mixq);
+void DSOUND_PerformMix(IDirectSoundImpl *dsound);
+void CALLBACK DSOUND_timer(UINT timerID, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
+void CALLBACK DSOUND_callback(HWAVEOUT hwo, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2);
+
+/* sound3d.c */
+
+void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb);
+
+#define STATE_STOPPED 0
+#define STATE_STARTING 1
+#define STATE_PLAYING 2
+#define STATE_CAPTURING 2
+#define STATE_STOPPING 3
+
+#define DSOUND_FREQSHIFT (14)
+
+extern IDirectSoundImpl* dsound;
+
+extern HRESULT mmErr(UINT err);
+extern void setup_dsound_options(void);
diff -u --unidirectional-new-file dlls/dsound/dsound.spec /home/wine/wine.save6/dlls/dsound/dsound.spec
--- dlls/dsound/dsound.spec 2004-06-30 15:55:33.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/dsound.spec 2004-03-10 18:39:28.000000000 -0500
@@ -1,4 +1,4 @@
-1 stdcall DirectSoundCreate(ptr ptr ptr)
+1 stdcall DirectSoundCreate(ptr ptr ptr) DirectSoundCreate8
2 stdcall DirectSoundEnumerateA(ptr ptr)
3 stdcall DirectSoundEnumerateW(ptr ptr)
4 stdcall -private DllCanUnloadNow() DSOUND_DllCanUnloadNow
diff -u --unidirectional-new-file dlls/dsound/dsound.spec.c /home/wine/wine.save6/dlls/dsound/dsound.spec.c
--- dlls/dsound/dsound.spec.c 1969-12-31 19:00:00.000000000 -0500
+++ /home/wine/wine.save6/dlls/dsound/dsound.spec.c 2004-03-16 21:19:28.000000000 -0500
@@ -0,0 +1,653 @@
+/* File generated automatically from ./dsound.spec; do not edit! */
+/* This file can be copied, modified and distributed without restriction. */
+
+extern char __wine_spec_pe_header[];
+#ifndef __GNUC__
+static void __asm__dummy_header(void) {
+#endif
+asm(".text\n\t"
+ ".align 4096\n"
+ "__wine_spec_pe_header:\t.skip 65536\n\t"
+ ".data\n\t"
+ ".align 4\n"
+ "__wine_spec_data_start:\t.long 1");
+#ifndef __GNUC__
+}
+#endif
+extern char _end[];
+extern int __wine_spec_data_start[], __wine_spec_exports[];
+
+#define __stdcall __attribute__((__stdcall__))
+
+#ifndef __GNUC__
+static void __asm__dummy(void) {
+#endif /* !defined(__GNUC__) */
+asm(".data\n"
+ "\t.align 4\n"
+ "__wine_spec_exports:\n"
+ "\t.long 0\n"
+ "\t.long 0\n"
+ "\t.long 0\n"
+ "\t.long __wine_spec_exp_names\n"
+ "\t.long 1\n"
+ "\t.long 14\n"
+ "\t.long 14\n"
+ "\t.long __wine_spec_exports_funcs\n"
+ "\t.long __wine_spec_exp_name_ptrs\n"
+ "\t.long __wine_spec_exp_ordinals\n"
+ "__wine_spec_exports_funcs:\n"
+ "\t.long DirectSoundCreate8\n"
+ "\t.long DirectSoundEnumerateA\n"
+ "\t.long DirectSoundEnumerateW\n"
+ "\t.long DSOUND_DllCanUnloadNow\n"
+ "\t.long DSOUND_DllGetClassObject\n"
+ "\t.long DirectSoundCaptureCreate8\n"
+ "\t.long DirectSoundCaptureEnumerateA\n"
+ "\t.long DirectSoundCaptureEnumerateW\n"
+ "\t.long GetDeviceID\n"
+ "\t.long DirectSoundFullDuplexCreate\n"
+ "\t.long DirectSoundCreate8\n"
+ "\t.long DirectSoundCaptureCreate8\n"
+ "\t.long DSOUND_DllRegisterServer\n"
+ "\t.long DSOUND_DllUnregisterServer\n"
+ "__wine_spec_exp_name_ptrs:\n"
+ "\t.long __wine_spec_exp_names+11\n"
+ "\t.long __wine_spec_exp_names+36\n"
+ "\t.long __wine_spec_exp_names+62\n"
+ "\t.long __wine_spec_exp_names+91\n"
+ "\t.long __wine_spec_exp_names+120\n"
+ "\t.long __wine_spec_exp_names+138\n"
+ "\t.long __wine_spec_exp_names+157\n"
+ "\t.long __wine_spec_exp_names+179\n"
+ "\t.long __wine_spec_exp_names+201\n"
+ "\t.long __wine_spec_exp_names+229\n"
+ "\t.long __wine_spec_exp_names+245\n"
+ "\t.long __wine_spec_exp_names+263\n"
+ "\t.long __wine_spec_exp_names+281\n"
+ "\t.long __wine_spec_exp_names+301\n"
+ "\t.text\n"
+ "__wine_spec_exp_names:\n"
+ "\t.string \"dsound.dll\"\n"
+ "\t.string \"DirectSoundCaptureCreate\"\n"
+ "\t.string \"DirectSoundCaptureCreate8\"\n"
+ "\t.string \"DirectSoundCaptureEnumerateA\"\n"
+ "\t.string \"DirectSoundCaptureEnumerateW\"\n"
+ "\t.string \"DirectSoundCreate\"\n"
+ "\t.string \"DirectSoundCreate8\"\n"
+ "\t.string \"DirectSoundEnumerateA\"\n"
+ "\t.string \"DirectSoundEnumerateW\"\n"
+ "\t.string \"DirectSoundFullDuplexCreate\"\n"
+ "\t.string \"DllCanUnloadNow\"\n"
+ "\t.string \"DllGetClassObject\"\n"
+ "\t.string \"DllRegisterServer\"\n"
+ "\t.string \"DllUnregisterServer\"\n"
+ "\t.string \"GetDeviceID\"\n"
+ "\t.data\n"
+ "__wine_spec_exp_ordinals:\n"
+ "\t.short 5\n"
+ "\t.short 11\n"
+ "\t.short 6\n"
+ "\t.short 7\n"
+ "\t.short 0\n"
+ "\t.short 10\n"
+ "\t.short 1\n"
+ "\t.short 2\n"
+ "\t.short 9\n"
+ "\t.short 3\n"
+ "\t.short 4\n"
+ "\t.short 12\n"
+ "\t.short 13\n"
+ "\t.short 8\n"
+ "\tjmp DirectSoundCreate8\n"
+ "\tret $12\n"
+ "\t.long DirectSoundCreate8,0x00000000\n"
+ "\tjmp DirectSoundEnumerateA\n"
+ "\tret $8\n"
+ "\t.long DirectSoundEnumerateA,0x00000000\n"
+ "\tjmp DirectSoundEnumerateW\n"
+ "\tret $8\n"
+ "\t.long DirectSoundEnumerateW,0x00000000\n"
+ "\tjmp DSOUND_DllCanUnloadNow\n"
+ "\tret $0\n"
+ "\t.long DSOUND_DllCanUnloadNow,0x00000000\n"
+ "\tjmp DSOUND_DllGetClassObject\n"
+ "\tret $12\n"
+ "\t.long DSOUND_DllGetClassObject,0x00000000\n"
+ "\tjmp DirectSoundCaptureCreate8\n"
+ "\tret $12\n"
+ "\t.long DirectSoundCaptureCreate8,0x00000000\n"
+ "\tjmp DirectSoundCaptureEnumerateA\n"
+ "\tret $8\n"
+ "\t.long DirectSoundCaptureEnumerateA,0x00000000\n"
+ "\tjmp DirectSoundCaptureEnumerateW\n"
+ "\tret $8\n"
+ "\t.long DirectSoundCaptureEnumerateW,0x00000000\n"
+ "\tjmp GetDeviceID\n"
+ "\tret $8\n"
+ "\t.long GetDeviceID,0x00000000\n"
+ "\tjmp DirectSoundFullDuplexCreate\n"
+ "\tret $40\n"
+ "\t.long DirectSoundFullDuplexCreate,0x00000000\n"
+ "\tjmp DirectSoundCreate8\n"
+ "\tret $12\n"
+ "\t.long DirectSoundCreate8,0x00000000\n"
+ "\tjmp DirectSoundCaptureCreate8\n"
+ "\tret $12\n"
+ "\t.long DirectSoundCaptureCreate8,0x00000000\n"
+ "\tjmp DSOUND_DllRegisterServer\n"
+ "\tret $0\n"
+ "\t.long DSOUND_DllRegisterServer,0x00000000\n"
+ "\tjmp DSOUND_DllUnregisterServer\n"
+ "\tret $0\n"
+ "\t.long DSOUND_DllUnregisterServer,0x00000000\n"
+ "\t.text\n"
+ "\t.align 4\n"
+);
+
+#ifndef __GNUC__
+}
+#endif /* !defined(__GNUC__) */
+
+static struct {
+ struct {
+ void *OriginalFirstThunk;
+ unsigned int TimeDateStamp;
+ unsigned int ForwarderChain;
+ const char *Name;
+ void *FirstThunk;
+ } imp[7];
+ const char *data[69];
+} imports = {
+ {
+ { 0, 0, 0, "winmm.dll", &imports.data[0] },
+ { 0, 0, 0, "ole32.dll", &imports.data[30] },
+ { 0, 0, 0, "user32.dll", &imports.data[32] },
+ { 0, 0, 0, "advapi32.dll", &imports.data[34] },
+ { 0, 0, 0, "kernel32.dll", &imports.data[46] },
+ { 0, 0, 0, "ntdll.dll", &imports.data[63] },
+ { 0, 0, 0, 0, 0 },
+ },
+ {
+ /* winmm.dll */
+ "\212\000timeBeginPeriod",
+ "\213\000timeEndPeriod",
+ "\217\000timeKillEvent",
+ "\220\000timeSetEvent",
+ "\221\000waveInAddBuffer",
+ "\222\000waveInClose",
+ "\223\000waveInGetDevCapsA",
+ "\230\000waveInGetNumDevs",
+ "\231\000waveInGetPosition",
+ "\232\000waveInMessage",
+ "\233\000waveInOpen",
+ "\234\000waveInPrepareHeader",
+ "\235\000waveInReset",
+ "\236\000waveInStart",
+ "\237\000waveInStop",
+ "\240\000waveInUnprepareHeader",
+ "\242\000waveOutClose",
+ "\243\000waveOutGetDevCapsA",
+ "\250\000waveOutGetNumDevs",
+ "\253\000waveOutGetPosition",
+ "\255\000waveOutMessage",
+ "\256\000waveOutOpen",
+ "\257\000waveOutPause",
+ "\260\000waveOutPrepareHeader",
+ "\261\000waveOutReset",
+ "\262\000waveOutRestart",
+ "\265\000waveOutSetVolume",
+ "\266\000waveOutUnprepareHeader",
+ "\267\000waveOutWrite",
+ 0,
+ /* ole32.dll */
+ "\373\000StringFromGUID2",
+ 0,
+ /* user32.dll */
+ "\262\002wsprintfW",
+ 0,
+ /* advapi32.dll */
+ "\352\000RegCloseKey",
+ "\356\000RegCreateKeyExA",
+ "\357\000RegCreateKeyExW",
+ "\362\000RegDeleteKeyW",
+ "\367\000RegEnumKeyExW",
+ "\001\001RegOpenKeyA",
+ "\002\001RegOpenKeyExA",
+ "\003\001RegOpenKeyExW",
+ "\013\001RegQueryValueExA",
+ "\027\001RegSetValueExA",
+ "\030\001RegSetValueExW",
+ 0,
+ /* kernel32.dll */
+ "\373\000DeleteCriticalSection",
+ "\013\001EnterCriticalSection",
+ "\052\001ExitProcess",
+ "\000\002GetModuleFileNameA",
+ "\127\002GetTickCount",
+ "\214\002HeapAlloc",
+ "\222\002HeapFree",
+ "\225\002HeapReAlloc",
+ "\236\002InitializeCriticalSection",
+ "\307\002LeaveCriticalSection",
+ "\365\002MulDiv",
+ "\366\002MultiByteToWideChar",
+ "\244\003SetEvent",
+ "\335\003Sleep",
+ "\141\004lstrlenA",
+ "\142\004lstrlenW",
+ 0,
+ /* ntdll.dll */
+ "\024\001RtlAcquireResourceExclusive",
+ "\025\001RtlAcquireResourceShared",
+ "\150\001RtlDeleteResource",
+ "\320\001RtlInitializeResource",
+ "\027\002RtlReleaseResource",
+ 0,
+ }
+};
+
+#ifndef __GNUC__
+static void __asm__dummy_import(void) {
+#endif
+
+asm(".data\n\t.align 8\n"
+ "\t.type timeBeginPeriod, at function\n"
+ "\t.globl timeBeginPeriod\n"
+ "timeBeginPeriod:\n\tjmp *(imports+140)\n\tmovl %esi,%esi\n"
+ "\t.type timeEndPeriod, at function\n"
+ "\t.globl timeEndPeriod\n"
+ "timeEndPeriod:\n\tjmp *(imports+144)\n\tmovl %esi,%esi\n"
+ "\t.type timeKillEvent, at function\n"
+ "\t.globl timeKillEvent\n"
+ "timeKillEvent:\n\tjmp *(imports+148)\n\tmovl %esi,%esi\n"
+ "\t.type timeSetEvent, at function\n"
+ "\t.globl timeSetEvent\n"
+ "timeSetEvent:\n\tjmp *(imports+152)\n\tmovl %esi,%esi\n"
+ "\t.type waveInAddBuffer, at function\n"
+ "\t.globl waveInAddBuffer\n"
+ "waveInAddBuffer:\n\tjmp *(imports+156)\n\tmovl %esi,%esi\n"
+ "\t.type waveInClose, at function\n"
+ "\t.globl waveInClose\n"
+ "waveInClose:\n\tjmp *(imports+160)\n\tmovl %esi,%esi\n"
+ "\t.type waveInGetDevCapsA, at function\n"
+ "\t.globl waveInGetDevCapsA\n"
+ "waveInGetDevCapsA:\n\tjmp *(imports+164)\n\tmovl %esi,%esi\n"
+ "\t.type waveInGetNumDevs, at function\n"
+ "\t.globl waveInGetNumDevs\n"
+ "waveInGetNumDevs:\n\tjmp *(imports+168)\n\tmovl %esi,%esi\n"
+ "\t.type waveInGetPosition, at function\n"
+ "\t.globl waveInGetPosition\n"
+ "waveInGetPosition:\n\tjmp *(imports+172)\n\tmovl %esi,%esi\n"
+ "\t.type waveInMessage, at function\n"
+ "\t.globl waveInMessage\n"
+ "waveInMessage:\n\tjmp *(imports+176)\n\tmovl %esi,%esi\n"
+ "\t.type waveInOpen, at function\n"
+ "\t.globl waveInOpen\n"
+ "waveInOpen:\n\tjmp *(imports+180)\n\tmovl %esi,%esi\n"
+ "\t.type waveInPrepareHeader, at function\n"
+ "\t.globl waveInPrepareHeader\n"
+ "waveInPrepareHeader:\n\tjmp *(imports+184)\n\tmovl %esi,%esi\n"
+ "\t.type waveInReset, at function\n"
+ "\t.globl waveInReset\n"
+ "waveInReset:\n\tjmp *(imports+188)\n\tmovl %esi,%esi\n"
+ "\t.type waveInStart, at function\n"
+ "\t.globl waveInStart\n"
+ "waveInStart:\n\tjmp *(imports+192)\n\tmovl %esi,%esi\n"
+ "\t.type waveInStop, at function\n"
+ "\t.globl waveInStop\n"
+ "waveInStop:\n\tjmp *(imports+196)\n\tmovl %esi,%esi\n"
+ "\t.type waveInUnprepareHeader, at function\n"
+ "\t.globl waveInUnprepareHeader\n"
+ "waveInUnprepareHeader:\n\tjmp *(imports+200)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutClose, at function\n"
+ "\t.globl waveOutClose\n"
+ "waveOutClose:\n\tjmp *(imports+204)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutGetDevCapsA, at function\n"
+ "\t.globl waveOutGetDevCapsA\n"
+ "waveOutGetDevCapsA:\n\tjmp *(imports+208)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutGetNumDevs, at function\n"
+ "\t.globl waveOutGetNumDevs\n"
+ "waveOutGetNumDevs:\n\tjmp *(imports+212)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutGetPosition, at function\n"
+ "\t.globl waveOutGetPosition\n"
+ "waveOutGetPosition:\n\tjmp *(imports+216)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutMessage, at function\n"
+ "\t.globl waveOutMessage\n"
+ "waveOutMessage:\n\tjmp *(imports+220)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutOpen, at function\n"
+ "\t.globl waveOutOpen\n"
+ "waveOutOpen:\n\tjmp *(imports+224)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutPause, at function\n"
+ "\t.globl waveOutPause\n"
+ "waveOutPause:\n\tjmp *(imports+228)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutPrepareHeader, at function\n"
+ "\t.globl waveOutPrepareHeader\n"
+ "waveOutPrepareHeader:\n\tjmp *(imports+232)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutReset, at function\n"
+ "\t.globl waveOutReset\n"
+ "waveOutReset:\n\tjmp *(imports+236)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutRestart, at function\n"
+ "\t.globl waveOutRestart\n"
+ "waveOutRestart:\n\tjmp *(imports+240)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutSetVolume, at function\n"
+ "\t.globl waveOutSetVolume\n"
+ "waveOutSetVolume:\n\tjmp *(imports+244)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutUnprepareHeader, at function\n"
+ "\t.globl waveOutUnprepareHeader\n"
+ "waveOutUnprepareHeader:\n\tjmp *(imports+248)\n\tmovl %esi,%esi\n"
+ "\t.type waveOutWrite, at function\n"
+ "\t.globl waveOutWrite\n"
+ "waveOutWrite:\n\tjmp *(imports+252)\n\tmovl %esi,%esi\n"
+ "\t.type StringFromGUID2, at function\n"
+ "\t.globl StringFromGUID2\n"
+ "StringFromGUID2:\n\tjmp *(imports+260)\n\tmovl %esi,%esi\n"
+ "\t.type wsprintfW, at function\n"
+ "\t.globl wsprintfW\n"
+ "wsprintfW:\n\tjmp *(imports+268)\n\tmovl %esi,%esi\n"
+ "\t.type RegCloseKey, at function\n"
+ "\t.globl RegCloseKey\n"
+ "RegCloseKey:\n\tjmp *(imports+276)\n\tmovl %esi,%esi\n"
+ "\t.type RegCreateKeyExA, at function\n"
+ "\t.globl RegCreateKeyExA\n"
+ "RegCreateKeyExA:\n\tjmp *(imports+280)\n\tmovl %esi,%esi\n"
+ "\t.type RegCreateKeyExW, at function\n"
+ "\t.globl RegCreateKeyExW\n"
+ "RegCreateKeyExW:\n\tjmp *(imports+284)\n\tmovl %esi,%esi\n"
+ "\t.type RegDeleteKeyW, at function\n"
+ "\t.globl RegDeleteKeyW\n"
+ "RegDeleteKeyW:\n\tjmp *(imports+288)\n\tmovl %esi,%esi\n"
+ "\t.type RegEnumKeyExW, at function\n"
+ "\t.globl RegEnumKeyExW\n"
+ "RegEnumKeyExW:\n\tjmp *(imports+292)\n\tmovl %esi,%esi\n"
+ "\t.type RegOpenKeyA, at function\n"
+ "\t.globl RegOpenKeyA\n"
+ "RegOpenKeyA:\n\tjmp *(imports+296)\n\tmovl %esi,%esi\n"
+ "\t.type RegOpenKeyExA, at function\n"
+ "\t.globl RegOpenKeyExA\n"
+ "RegOpenKeyExA:\n\tjmp *(imports+300)\n\tmovl %esi,%esi\n"
+ "\t.type RegOpenKeyExW, at function\n"
+ "\t.globl RegOpenKeyExW\n"
+ "RegOpenKeyExW:\n\tjmp *(imports+304)\n\tmovl %esi,%esi\n"
+ "\t.type RegQueryValueExA, at function\n"
+ "\t.globl RegQueryValueExA\n"
+ "RegQueryValueExA:\n\tjmp *(imports+308)\n\tmovl %esi,%esi\n"
+ "\t.type RegSetValueExA, at function\n"
+ "\t.globl RegSetValueExA\n"
+ "RegSetValueExA:\n\tjmp *(imports+312)\n\tmovl %esi,%esi\n"
+ "\t.type RegSetValueExW, at function\n"
+ "\t.globl RegSetValueExW\n"
+ "RegSetValueExW:\n\tjmp *(imports+316)\n\tmovl %esi,%esi\n"
+ "\t.type DeleteCriticalSection, at function\n"
+ "\t.globl DeleteCriticalSection\n"
+ "DeleteCriticalSection:\n\tjmp *(imports+324)\n\tmovl %esi,%esi\n"
+ "\t.type EnterCriticalSection, at function\n"
+ "\t.globl EnterCriticalSection\n"
+ "EnterCriticalSection:\n\tjmp *(imports+328)\n\tmovl %esi,%esi\n"
+ "\t.type ExitProcess, at function\n"
+ "\t.globl ExitProcess\n"
+ "ExitProcess:\n\tjmp *(imports+332)\n\tmovl %esi,%esi\n"
+ "\t.type GetModuleFileNameA, at function\n"
+ "\t.globl GetModuleFileNameA\n"
+ "GetModuleFileNameA:\n\tjmp *(imports+336)\n\tmovl %esi,%esi\n"
+ "\t.type GetTickCount, at function\n"
+ "\t.globl GetTickCount\n"
+ "GetTickCount:\n\tjmp *(imports+340)\n\tmovl %esi,%esi\n"
+ "\t.type HeapAlloc, at function\n"
+ "\t.globl HeapAlloc\n"
+ "HeapAlloc:\n\tjmp *(imports+344)\n\tmovl %esi,%esi\n"
+ "\t.type HeapFree, at function\n"
+ "\t.globl HeapFree\n"
+ "HeapFree:\n\tjmp *(imports+348)\n\tmovl %esi,%esi\n"
+ "\t.type HeapReAlloc, at function\n"
+ "\t.globl HeapReAlloc\n"
+ "HeapReAlloc:\n\tjmp *(imports+352)\n\tmovl %esi,%esi\n"
+ "\t.type InitializeCriticalSection, at function\n"
+ "\t.globl InitializeCriticalSection\n"
+ "InitializeCriticalSection:\n\tjmp *(imports+356)\n\tmovl %esi,%esi\n"
+ "\t.type LeaveCriticalSection, at function\n"
+ "\t.globl LeaveCriticalSection\n"
+ "LeaveCriticalSection:\n\tjmp *(imports+360)\n\tmovl %esi,%esi\n"
+ "\t.type MulDiv, at function\n"
+ "\t.globl MulDiv\n"
+ "MulDiv:\n\tjmp *(imports+364)\n\tmovl %esi,%esi\n"
+ "\t.type MultiByteToWideChar, at function\n"
+ "\t.globl MultiByteToWideChar\n"
+ "MultiByteToWideChar:\n\tjmp *(imports+368)\n\tmovl %esi,%esi\n"
+ "\t.type SetEvent, at function\n"
+ "\t.globl SetEvent\n"
+ "SetEvent:\n\tjmp *(imports+372)\n\tmovl %esi,%esi\n"
+ "\t.type Sleep, at function\n"
+ "\t.globl Sleep\n"
+ "Sleep:\n\tjmp *(imports+376)\n\tmovl %esi,%esi\n"
+ "\t.type lstrlenA, at function\n"
+ "\t.globl lstrlenA\n"
+ "lstrlenA:\n\tjmp *(imports+380)\n\tmovl %esi,%esi\n"
+ "\t.type lstrlenW, at function\n"
+ "\t.globl lstrlenW\n"
+ "lstrlenW:\n\tjmp *(imports+384)\n\tmovl %esi,%esi\n"
+ "\t.type RtlAcquireResourceExclusive, at function\n"
+ "\t.globl RtlAcquireResourceExclusive\n"
+ "RtlAcquireResourceExclusive:\n\tjmp *(imports+392)\n\tmovl %esi,%esi\n"
+ "\t.type RtlAcquireResourceShared, at function\n"
+ "\t.globl RtlAcquireResourceShared\n"
+ "RtlAcquireResourceShared:\n\tjmp *(imports+396)\n\tmovl %esi,%esi\n"
+ "\t.type RtlDeleteResource, at function\n"
+ "\t.globl RtlDeleteResource\n"
+ "RtlDeleteResource:\n\tjmp *(imports+400)\n\tmovl %esi,%esi\n"
+ "\t.type RtlInitializeResource, at function\n"
+ "\t.globl RtlInitializeResource\n"
+ "RtlInitializeResource:\n\tjmp *(imports+404)\n\tmovl %esi,%esi\n"
+ "\t.type RtlReleaseResource, at function\n"
+ "\t.globl RtlReleaseResource\n"
+ "RtlReleaseResource:\n\tjmp *(imports+408)\n\tmovl %esi,%esi\n"
+".text");
+#ifndef __GNUC__
+}
+#endif
+
+static const unsigned int res_0[219] = {
+ 0x0034036c,0x00560000,0x005f0053,0x00450056,0x00530052,0x004f0049,0x005f004e,0x004e0049,
+ 0x004f0046,0x00000000,0xfeef04bd,0x00010000,0x00040008,0x00010371,0x00040008,0x00010371,
+ 0x00000000,0x00000000,0x00000000,0x00000002,0x00000000,0x00000000,0x00000000,0x000002cc,
+ 0x00530000,0x00720074,0x006e0069,0x00460067,0x006c0069,0x00490065,0x0066006e,0x0000006f,
+ 0x000002a8,0x00300000,0x00300034,0x00300039,0x00450034,0x00000034,0x000a0034,0x00430001,
+ 0x006d006f,0x00610070,0x0079006e,0x0061004e,0x0065006d,0x00000000,0x00690057,0x0065006e,
+ 0x00540020,0x00610065,0x0000006d,0x0011004a,0x00460001,0x006c0069,0x00440065,0x00730065,
+ 0x00720063,0x00700069,0x00690074,0x006e006f,0x00000000,0x00690057,0x0065006e,0x00440020,
+ 0x00720069,0x00630065,0x00530074,0x0075006f,0x0064006e,0x00000000,0x000a0034,0x00460001,
+ 0x006c0069,0x00560065,0x00720065,0x00690073,0x006e006f,0x00000000,0x002e0034,0x002e0038,
+ 0x002e0031,0x00380038,0x00000031,0x000b0036,0x00490001,0x0074006e,0x00720065,0x0061006e,
+ 0x004e006c,0x006d0061,0x00000065,0x00730064,0x0075006f,0x0064006e,0x0064002e,0x006c006c,
+ 0x00000000,0x005c00dc,0x004c0001,0x00670065,0x006c0061,0x006f0043,0x00790070,0x00690072,
+ 0x00680067,0x00000074,0x006f0043,0x00790070,0x00690072,0x00680067,0x00200074,0x00630028,
+ 0x00200029,0x00390031,0x00330039,0x0032002d,0x00300030,0x00200034,0x00680074,0x00200065,
+ 0x00690057,0x0065006e,0x00700020,0x006f0072,0x0065006a,0x00740063,0x00610020,0x00740075,
+ 0x006f0068,0x00730072,0x00280020,0x00650073,0x00200065,0x00680074,0x00200065,0x00690066,
+ 0x0065006c,0x00410020,0x00540055,0x004f0048,0x00530052,0x00660020,0x0072006f,0x00610020,
+ 0x00630020,0x006d006f,0x006c0070,0x00740065,0x00200065,0x0069006c,0x00740073,0x00000029,
+ 0x000b003e,0x004f0001,0x00690072,0x00690067,0x0061006e,0x0046006c,0x006c0069,0x006e0065,
+ 0x006d0061,0x00000065,0x00730064,0x0075006f,0x0064006e,0x0064002e,0x006c006c,0x00000000,
+ 0x00080030,0x00500001,0x006f0072,0x00750064,0x00740063,0x0061004e,0x0065006d,0x00000000,
+ 0x00690044,0x00650072,0x00740063,0x00000058,0x0004002c,0x00500001,0x006f0072,0x00750064,
+ 0x00740063,0x00650056,0x00730072,0x006f0069,0x0000006e,0x002e0034,0x00000038,0x0001002a,
+ 0x004f0001,0x0045004c,0x00650053,0x0066006c,0x00650052,0x00690067,0x00740073,0x00720065,
+ 0x00000000,0x00000000,0x00000044,0x00560000,0x00720061,0x00690046,0x0065006c,0x006e0049,
+ 0x006f0066,0x00000000,0x00040024,0x00540000,0x00610072,0x0073006e,0x0061006c,0x00690074,
+ 0x006e006f,0x00000000,0x04e40409
+};
+
+struct res_dir {
+ unsigned int Characteristics;
+ unsigned int TimeDateStamp;
+ unsigned short MajorVersion, MinorVersion;
+ unsigned short NumerOfNamedEntries, NumberOfIdEntries;
+};
+
+struct res_dir_entry {
+ unsigned int Name;
+ unsigned int OffsetToData;
+};
+
+struct res_data_entry {
+ const unsigned int *OffsetToData;
+ unsigned int Size;
+ unsigned int CodePage;
+ unsigned int ResourceHandle;
+};
+
+#define OFFSETOF(field) ((char*)&((struct res_struct *)0)->field - (char*)((struct res_struct *) 0))
+static struct res_struct{
+ struct res_dir type_dir;
+ struct res_dir_entry type_entries[1];
+ struct res_dir name_0_dir;
+ struct res_dir_entry name_0_entries[1];
+ struct res_dir lang_0_0_dir;
+ struct res_dir_entry lang_0_0_entries[1];
+ struct res_data_entry data_entries[1];
+} resources = {
+ { 0, 0, 0, 0, 0, 1 },
+ {
+ { 0x0010, OFFSETOF(name_0_dir) | 0x80000000 },
+ },
+ { 0, 0, 0, 0, 0, 1 }, /* name_0_dir */
+ {
+ { 0x0001, OFFSETOF(lang_0_0_dir) | 0x80000000 },
+ },
+ { 0, 0, 0, 0, 0, 1 }, /* lang_0_0_dir */
+ {
+ { 0x0000, OFFSETOF(data_entries[0]) },
+ },
+ {
+ { res_0, sizeof(res_0), 0, 0 },
+ }
+};
+#undef OFFSETOF
+
+static int __wine_spec_init_state;
+extern int __wine_main_argc;
+extern char **__wine_main_argv;
+extern char **__wine_main_environ;
+extern unsigned short **__wine_main_wargv;
+extern void _init(int, char**, char**);
+extern void _fini();
+#ifdef __GNUC__
+# ifdef __APPLE__
+extern int __stdcall DllMain( void*, unsigned int, void* ) __attribute__((weak_import));
+# else
+extern int __stdcall DllMain( void*, unsigned int, void* ) __attribute__((weak));
+# endif
+#else
+extern int __stdcall DllMain( void*, unsigned int, void* );
+static void __asm__dummy_DllMain(void) { asm(".weak DllMain"); }
+#endif
+
+static int __stdcall __wine_dll_main( void *inst, unsigned int reason, void *reserved )
+{
+ int ret;
+ if (reason == 1 && __wine_spec_init_state == 1)
+ _init( __wine_main_argc, __wine_main_argv, __wine_main_environ );
+ ret = DllMain ? DllMain( inst, reason, reserved ) : 1;
+ if (reason == 0 && __wine_spec_init_state == 1) _fini();
+ return ret;
+}
+static const struct image_nt_headers
+{
+ int Signature;
+ struct file_header {
+ short Machine;
+ short NumberOfSections;
+ int TimeDateStamp;
+ void *PointerToSymbolTable;
+ int NumberOfSymbols;
+ short SizeOfOptionalHeader;
+ short Characteristics;
+ } FileHeader;
+ struct opt_header {
+ short Magic;
+ char MajorLinkerVersion, MinorLinkerVersion;
+ int SizeOfCode;
+ int SizeOfInitializedData;
+ int SizeOfUninitializedData;
+ void *AddressOfEntryPoint;
+ void *BaseOfCode;
+ void *BaseOfData;
+ void *ImageBase;
+ int SectionAlignment;
+ int FileAlignment;
+ short MajorOperatingSystemVersion;
+ short MinorOperatingSystemVersion;
+ short MajorImageVersion;
+ short MinorImageVersion;
+ short MajorSubsystemVersion;
+ short MinorSubsystemVersion;
+ int Win32VersionValue;
+ void *SizeOfImage;
+ int SizeOfHeaders;
+ int CheckSum;
+ short Subsystem;
+ short DllCharacteristics;
+ int SizeOfStackReserve;
+ int SizeOfStackCommit;
+ int SizeOfHeapReserve;
+ int SizeOfHeapCommit;
+ int LoaderFlags;
+ int NumberOfRvaAndSizes;
+ struct { const void *VirtualAddress; int Size; } DataDirectory[16];
+ } OptionalHeader;
+} nt_header = {
+ 0x4550,
+ { 0x014c,
+ 0, 0, 0, 0,
+ sizeof(nt_header.OptionalHeader),
+ 0x2000 },
+ { 0x010b,
+ 0, 0,
+ 0, 0, 0,
+ __wine_dll_main,
+ 0, __wine_spec_data_start,
+ __wine_spec_pe_header,
+ 4096,
+ 4096,
+ 1, 0,
+ 0, 0,
+ 4, 0,
+ 0,
+ _end,
+ 4096,
+ 0,
+ 0x0000,
+ 0,
+ 1048576, 4096,
+ 1048576, 4096,
+ 0,
+ 16,
+ {
+ { __wine_spec_exports, 180 },
+ { &imports, sizeof(imports) },
+ { &resources, sizeof(resources) },
+ }
+ }
+};
+
+void __wine_spec_init(void)
+{
+ extern void __wine_dll_register( const struct image_nt_headers *, const char * );
+ __wine_spec_init_state = 1;
+ __wine_dll_register( &nt_header, "dsound.dll" );
+}
+
+#ifndef __GNUC__
+static void __asm__dummy_dll_init(void) {
+#endif
+asm("\t.section\t\".init\" ,\"ax\"\n"
+ "\tcall __wine_spec_init_ctor\n"
+ "\t.section\t\".text\"\n");
+#ifndef __GNUC__
+}
+#endif
+void __wine_spec_init_ctor(void)
+{
+ if (__wine_spec_init_state) return;
+ __wine_spec_init();
+ __wine_spec_init_state = 2;
+}
diff -u --unidirectional-new-file dlls/dsound/dsound.spec.def /home/wine/wine.save6/dlls/dsound/dsound.spec.def
--- dlls/dsound/dsound.spec.def 2004-06-30 19:22:21.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/dsound.spec.def 2004-03-15 20:46:45.000000000 -0500
@@ -3,7 +3,7 @@
LIBRARY dsound.dll
EXPORTS
- DirectSoundCreate at 12 @1
+ DirectSoundCreate at 12=DirectSoundCreate8 at 12 @1
DirectSoundEnumerateA at 8 @2
DirectSoundEnumerateW at 8 @3
DllCanUnloadNow at 0=DSOUND_DllCanUnloadNow at 0 @4 PRIVATE
Binary files dlls/dsound/dsound.spec.o and /home/wine/wine.save6/dlls/dsound/dsound.spec.o differ
diff -u --unidirectional-new-file dlls/dsound/Makefile /home/wine/wine.save6/dlls/dsound/Makefile
--- dlls/dsound/Makefile 2004-06-30 19:37:31.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/Makefile 2004-03-16 21:18:01.000000000 -0500
@@ -9,7 +9,6 @@
C_SRCS = \
buffer.c \
capture.c \
- dsound.c \
dsound_main.c \
mixer.c \
primary.c \
@@ -29,7 +28,7 @@
# ALTNAMES : alternate names for this dll (optional)
# EXTRALIBS : extra libraries to link in (optional)
# SPEC_SRCS16 : interface definition files for 16-bit dlls (optional)
-# SUBSYSTEM : (optional) subsystem (for native dlls)
+# DLLMODE : (optional) subsystem mode (for native dlls)
#
# plus all variables required by the global Make.rules.in
#
@@ -73,7 +72,7 @@
CC = gcc
CFLAGS = -g -O2
CPPFLAGS =
-LIBS =
+LIBS = -lm
BISON = bison
YACC = $(BISON) -y
LEX = flex
@@ -96,10 +95,13 @@
AS = as
LD = ld
LDFLAGS =
+LDCOMBINE = $(LD) -r
RM = rm -f
MV = mv
LINT =
LINTFLAGS =
+LDDLLFLAGS = -shared -Wl,-Bsymbolic,-z,defs,-init,__wine_spec_init,-fini,__wine_spec_fini
+LDDLL = $(CC) $(LDDLLFLAGS)
INCLUDES = -I$(SRCDIR) -I. -I$(TOPSRCDIR)/include -I$(TOPOBJDIR)/include $(EXTRAINCL)
EXTRACFLAGS = -Wall -pipe -mpreferred-stack-boundary=2 -fno-strict-aliasing -gstabs+ -Wpointer-arith
ALLCFLAGS = $(INCLUDES) $(DEFS) $(DLLFLAGS) $(EXTRACFLAGS) $(CPPFLAGS) $(CFLAGS)
@@ -324,8 +326,11 @@
# Rules for .so files
-$(MODULE).so: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) Makefile.in
- $(WINEGCC) -B$(TOOLSDIR)/tools/winebuild -shared $(SRCDIR)/$(MAINSPEC) $(ALL_OBJS) $(RC_SRCS:.rc=.res) $(SUBSYSTEM:%=-Wb,--subsystem,%) -o $@ -L$(DLLDIR) $(DELAYIMPORTS:%=-Wb,-d%) $(IMPORTS:%=-l%) $(ALL_LIBS)
+$(MAINSPEC).c: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) $(WINEBUILD)
+ $(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --dll $(SRCDIR)/$(MAINSPEC) $(DLLMODE:%=--mode %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
+
+$(MODULE).so: $(MAINSPEC).o $(ALL_OBJS) Makefile.in
+ $(LDDLL) $(MAINSPEC).o $(ALL_OBJS) -o $@ -L$(DLLDIR) $(ALL_LIBS) -lc
# Rules for .dll files
@@ -341,7 +346,7 @@
$(WIN16_FILES:%=__checklink16__%): checklink16
checklink16:: $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o dummy
- $(CC) -o checklink -Wl,-rpath,$(TOPOBJDIR)/libs $(TOPSRCDIR)/dlls/checklink.c $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(ALL_LIBS) -lm && $(RM) checklink $(MAINSPEC).c $(MAINSPEC).o
+ $(CC) -o checklink -Wl,-rpath,$(TOPOBJDIR)/libs $(TOPSRCDIR)/dlls/checklink.c $(MAINSPEC).o $(OBJS) $(MODULE).dbg.o -L$(DLLDIR) $(ALL_LIBS) && $(RM) checklink
checklink:: $(WIN16_FILES:%=__checklink16__%)
@@ -351,11 +356,6 @@
crosstest:: $(SUBDIRS:%=%/__crosstest__)
-# Rule to explicitly generate the .spec.c for debugging
-
-$(MAINSPEC).c: $(MAINSPEC) $(RC_SRCS:.rc=.res) $(ALL_OBJS) $(IMPORTLIBS) $(WINEBUILD)
- $(WINEBUILD) $(DEFS) $(DLLFLAGS) -o $@ --dll $(SRCDIR)/$(MAINSPEC) $(SUBSYSTEM:%=--subsystem %) $(RC_SRCS:.rc=.res) $(ALL_OBJS) -L$(DLLDIR) $(DELAYIMPORTS:%=-d%) $(IMPORTS:%=-l%)
-
# Rules for auto documentation
man: $(C_SRCS)
@@ -443,32 +443,6 @@
../../include/imm.h ../../include/rpcdce.h ../../include/rpcdcep.h \
../../include/rpcnterr.h ../../include/cguid.h \
../../include/dsdriver.h ./dsound_private.h
-dsound.o: dsound.c ../../include/config.h ../../include/wine/port.h \
- ../../include/windef.h ../../include/winnt.h ../../include/basetsd.h \
- ../../include/pshpack2.h ../../include/poppack.h \
- ../../include/pshpack4.h ../../include/guiddef.h \
- ../../include/winbase.h ../../include/winerror.h \
- ../../include/winreg.h ../../include/winuser.h ../../include/wingdi.h \
- ../../include/mmsystem.h ../../include/pshpack1.h \
- ../../include/winternl.h ../../include/mmddk.h \
- ../../include/wine/windef16.h ../../include/wine/winbase16.h \
- ../../include/winnls.h ../../include/wine/library.h \
- ../../include/wine/debug.h ../../include/dsound.h \
- ../../include/objbase.h ../../include/rpc.h ../../include/windows.h \
- ../../include/winresrc.h ../../include/commctrl.h \
- ../../include/prsht.h ../../include/dde.h ../../include/dlgs.h \
- ../../include/winver.h ../../include/excpt.h ../../include/wincon.h \
- ../../include/winnetwk.h ../../include/cderr.h ../../include/ddeml.h \
- ../../include/lzexpand.h ../../include/nb30.h \
- ../../include/shellapi.h ../../include/winsock2.h \
- ../../include/winsock.h ../../include/wincrypt.h \
- ../../include/winspool.h ../../include/ole2.h ../../include/oleauto.h \
- ../../include/oaidl.h ../../include/rpcndr.h ../../include/objidl.h \
- ../../include/unknwn.h ../../include/wtypes.h ../../include/oleidl.h \
- ../../include/commdlg.h ../../include/winsvc.h ../../include/mcx.h \
- ../../include/imm.h ../../include/rpcdce.h ../../include/rpcdcep.h \
- ../../include/rpcnterr.h ../../include/cguid.h \
- ../../include/dsdriver.h ./dsound_private.h ../../include/dsconf.h
dsound_main.o: dsound_main.c ../../include/config.h \
../../include/wine/port.h ../../include/windef.h \
../../include/winnt.h ../../include/basetsd.h \
diff -u --unidirectional-new-file dlls/dsound/Makefile.in /home/wine/wine.save6/dlls/dsound/Makefile.in
--- dlls/dsound/Makefile.in 2004-06-30 19:34:16.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/Makefile.in 2004-03-10 18:39:27.000000000 -0500
@@ -9,7 +9,6 @@
C_SRCS = \
buffer.c \
capture.c \
- dsound.c \
dsound_main.c \
mixer.c \
primary.c \
Binary files dlls/dsound/mixer.o and /home/wine/wine.save6/dlls/dsound/mixer.o differ
Only in dlls/dsound: old
Only in dlls/dsound: old1
Binary files dlls/dsound/primary.o and /home/wine/wine.save6/dlls/dsound/primary.o differ
Binary files dlls/dsound/propset.o and /home/wine/wine.save6/dlls/dsound/propset.o differ
Binary files dlls/dsound/regsvr.o and /home/wine/wine.save6/dlls/dsound/regsvr.o differ
diff -u --unidirectional-new-file dlls/dsound/.#sound3d.c.1.28 /home/wine/wine.save6/dlls/dsound/.#sound3d.c.1.28
--- dlls/dsound/.#sound3d.c.1.28 1969-12-31 19:00:00.000000000 -0500
+++ /home/wine/wine.save6/dlls/dsound/.#sound3d.c.1.28 2004-03-16 19:25:13.000000000 -0500
@@ -0,0 +1,1141 @@
+/* DirectSound
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998 Rob Riggs
+ * Copyright 2000-2001 TransGaming Technologies, Inc.
+ * Copyright 2002-2003 Rok Mandeljc <rok.mandeljc at gimb.org>
+ *
+ * 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 3D 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 <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#include <math.h> /* Insomnia - pow() function */
+
+#define NONAMELESSUNION
+#define NONAMELESSSTRUCT
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "mmsystem.h"
+#include "winreg.h"
+#include "winternl.h"
+#include "mmddk.h"
+#include "wine/windef16.h"
+#include "wine/debug.h"
+#include "dsound.h"
+#include "dsdriver.h"
+#include "dsound_private.h"
+
+/* default intensity level for human ears */
+#define DEFAULT_INTENSITY 0.000000000001f
+/* default velocity of sound in the air */
+#define DEFAULT_VELOCITY 340
+
+WINE_DEFAULT_DEBUG_CHANNEL(dsound3d);
+
+/*******************************************************************************
+ * 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->x*b->x) + (a->y*b->y) + (a->z*b->z);
+ TRACE("(%f,%f,%f) * (%f,%f,%f) = %f)\n", a->x, a->y, a->z, b->x, b->y, \
+ b->z, c);
+ return c;
+}
+
+/* vector product (i believe it's called cross product in english */
+static inline D3DVECTOR VectorProduct (LPD3DVECTOR a, LPD3DVECTOR b)
+{
+ D3DVECTOR c;
+ c.x = (a->y*b->z) - (a->z*b->y);
+ c.y = (a->z*b->x) - (a->x*b->z);
+ c.z = (a->x*b->y) - (a->y*b->x);
+ TRACE("(%f,%f,%f) x (%f,%f,%f) = (%f,%f,%f)\n", a->x, a->y, a->z, b->x, b->y, \
+ b->z, c.x, c.y, c.z);
+ return c;
+}
+
+/* magnitude (length) of vector */
+static inline D3DVALUE VectorMagnitude (LPD3DVECTOR a)
+{
+ D3DVALUE l;
+ l = sqrt (ScalarProduct (a, a));
+ TRACE("|(%f,%f,%f)| = %f\n", a->x, a->y, a->z, l);
+ return l;
+}
+
+/* conversion between radians and degrees */
+static inline D3DVALUE RadToDeg (D3DVALUE angle)
+{
+ D3DVALUE newangle;
+ newangle = angle * (360/(2*M_PI));
+ TRACE("%f rad = %f deg\n", angle, newangle);
+ return newangle;
+}
+
+/* conversion between degrees and radians */
+static inline D3DVALUE DegToRad (D3DVALUE angle)
+{
+ D3DVALUE newangle;
+ newangle = angle * (2*M_PI/360);
+ TRACE("%f deg = %f rad\n", angle, newangle);
+ return newangle;
+}
+
+/* angle between vectors - deg version */
+static inline D3DVALUE AngleBetweenVectorsDeg (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);
+ /* we now have angle in radians */
+ angle = RadToDeg(angle);
+ TRACE("angle between (%f,%f,%f) and (%f,%f,%f) = %f degrees\n", a->x, a->y, a->z, b->x,
+ b->y, b->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);
+ TRACE("angle between (%f,%f,%f) and (%f,%f,%f) = %f radians\n", a->x, a->y, a->z, b->x,
+ b->y, b->z, angle);
+ return angle;
+}
+
+/* calculates vector between two points */
+static inline D3DVECTOR VectorBetweenTwoPoints (LPD3DVECTOR a, LPD3DVECTOR b)
+{
+ D3DVECTOR c;
+ c.x = b->x - a->x;
+ c.y = b->y - a->y;
+ c.z = b->z - a->z;
+ TRACE("A (%f,%f,%f), B (%f,%f,%f), AB = (%f,%f,%f)\n", a->x, a->y, a->z, b->x, b->y,
+ b->z, c.x, c.y, c.z);
+ return c;
+}
+
+/* calculates the length of vector's projection on another vector */
+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->x, a->y, a->z, p->x,
+ p->y, p->z, result);
+ return result;
+}
+
+/*******************************************************************************
+ * 3D Buffer and Listener mixing
+ */
+
+void DSOUND_Calc3DBuffer(IDirectSoundBufferImpl *dsb)
+{
+ /* volume, at which the sound will be played after all calcs. */
+ D3DVALUE lVolume = 0;
+ /* intensity (used for distance related stuff) */
+ double flIntensity;
+ double flTemp;
+ /* stuff for distance related stuff calc. */
+ D3DVECTOR vDistance;
+ D3DVALUE flDistance = 0;
+ /* panning related stuff */
+ D3DVALUE flAngle;
+ D3DVECTOR vLeft;
+ /* doppler shift related stuff */
+#if 0
+ D3DVALUE flFreq, flBufferVel, flListenerVel;
+#endif
+
+ TRACE("(%p)\n",dsb);
+
+ /* initial buffer volume */
+ lVolume = dsb->ds3db_lVolume;
+
+ switch (dsb->ds3db_ds3db.dwMode)
+ {
+ case DS3DMODE_DISABLE:
+ TRACE("3D processing disabled\n");
+ /* this one is here only to eliminate annoying warning message */
+ DSOUND_RecalcVolPan (&dsb->volpan);
+ DSOUND_ForceRemix (dsb);
+ break;
+ case DS3DMODE_NORMAL:
+ TRACE("Normal 3D processing mode\n");
+ /* we need to calculate distance between buffer and listener*/
+ vDistance = VectorBetweenTwoPoints(&dsb->ds3db_ds3db.vPosition, &dsb->dsound->ds3dl.vPosition);
+ flDistance = VectorMagnitude (&vDistance);
+ break;
+ case DS3DMODE_HEADRELATIVE:
+ TRACE("Head-relative 3D processing mode\n");
+ /* distance between buffer and listener is same as buffer's position */
+ flDistance = VectorMagnitude (&dsb->ds3db_ds3db.vPosition);
+ break;
+ }
+
+ if (flDistance > dsb->ds3db_ds3db.flMaxDistance)
+ {
+ /* some apps don't want you to hear too distant sounds... */
+ if (dsb->dsbd.dwFlags & DSBCAPS_MUTE3DATMAXDISTANCE)
+ {
+ dsb->volpan.lVolume = DSBVOLUME_MIN;
+ DSOUND_RecalcVolPan (&dsb->volpan);
+ /* i guess mixing here would be a waste of power */
+ return;
+ }
+ else
+ flDistance = dsb->ds3db_ds3db.flMaxDistance;
+ }
+
+ if (flDistance < dsb->ds3db_ds3db.flMinDistance)
+ flDistance = dsb->ds3db_ds3db.flMinDistance;
+
+ /* 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 */
+ flIntensity = pow(10,lVolume)*DEFAULT_INTENSITY;
+ flTemp = (flDistance/dsb->ds3db_ds3db.flMinDistance)*(flDistance/dsb->ds3db_ds3db.flMinDistance);
+ flIntensity /= flTemp;
+ lVolume = log10(flIntensity/DEFAULT_INTENSITY);
+ lVolume *= 1000; /* convert back to hundreths of dB */
+ lVolume -= 10000; /* we need to do it in ms way */
+ TRACE("dist. att: Distance = %f, MinDistance = %f => adjusting volume %ld to %f\n", flDistance, dsb->ds3db_ds3db.flMinDistance, dsb->ds3db_lVolume, lVolume);
+
+ /* conning */
+ /* sometimes it happens that vConeOrientation vector = (0,0,0); in this case angle is "nan" and it's useless*/
+ if (dsb->ds3db_ds3db.vConeOrientation.x == 0 && dsb->ds3db_ds3db.vConeOrientation.y == 0 && dsb->ds3db_ds3db.vConeOrientation.z == 0)
+ {
+ TRACE("conning: cones not set\n");
+ }
+ else
+ {
+ /* calculate angle */
+ flAngle = AngleBetweenVectorsDeg(&dsb->ds3db_ds3db.vConeOrientation, &vDistance);
+ /* if by any chance it happens that OutsideConeAngle = InsideConeAngle (that means that conning has no effect) */
+ if (dsb->ds3db_ds3db.dwInsideConeAngle != dsb->ds3db_ds3db.dwOutsideConeAngle)
+ {
+ /* my test show that for my way of calc., we need only half of angles */
+ DWORD dwInsideConeAngle = dsb->ds3db_ds3db.dwInsideConeAngle/2;
+ DWORD dwOutsideConeAngle = dsb->ds3db_ds3db.dwOutsideConeAngle/2;
+ /* 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 */
+ lVolume += ((dsb->ds3db_ds3db.lConeOutsideVolume)/((dwOutsideConeAngle) - (dwInsideConeAngle))) * flAngle;
+ }
+ TRACE("conning: Angle = %f deg; InsideConeAngle(/2) = %ld deg; OutsideConeAngle(/2) = %ld deg; ConeOutsideVolume = %ld => adjusting volume to %f\n",
+ flAngle, dsb->ds3db_ds3db.dwInsideConeAngle/2, dsb->ds3db_ds3db.dwOutsideConeAngle/2, dsb->ds3db_ds3db.lConeOutsideVolume, lVolume);
+ }
+ dsb->volpan.lVolume = lVolume;
+
+ /* panning */
+ if (dsb->dsound->ds3dl.vPosition.x == dsb->ds3db_ds3db.vPosition.x &&
+ dsb->dsound->ds3dl.vPosition.y == dsb->ds3db_ds3db.vPosition.y &&
+ dsb->dsound->ds3dl.vPosition.z == dsb->ds3db_ds3db.vPosition.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);
+
+ /* FIXME: Doppler Effect disabled since i have no idea which frequency to change and how to do it */
+#if 0
+ /* doppler shift*/
+ if ((VectorMagnitude(&ds3db.vVelocity) == 0) && (VectorMagnitude(&dsb->dsound->ds3dl.vVelocity) == 0))
+ {
+ TRACE("doppler: Buffer and Listener don't have velocities\n");
+ }
+ else
+ {
+ /* calculate length of ds3db.vVelocity component which causes Doppler Effect
+ 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 */
+ flBufferVel = ProjectVector(&dsb->ds3db_ds3db.vVelocity, &vDistance);
+ /* calculate length of ds3dl.vVelocity component which causes Doppler Effect
+ 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 */
+ flListenerVel = ProjectVector(&dsb->dsound->ds3dl.vVelocity, &vDistance);
+ /* formula taken from Gianicoli D.: Physics, 4th edition: */
+ /* FIXME: replace dsb->freq with appropriate frequency ! */
+ flFreq = dsb->freq * ((DEFAULT_VELOCITY + flListenerVel)/(DEFAULT_VELOCITY + flBufferVel));
+ TRACE("doppler: Buffer velocity (component) = %lf, Listener velocity (component) = %lf => Doppler shift: %ld Hz -> %lf Hz\n", flBufferVel, flListenerVel, \
+ dsb->freq, flFreq);
+ /* FIXME: replace following line with correct frequency setting ! */
+ dsb->freq = flFreq;
+ }
+#endif
+
+ /* time for remix */
+ DSOUND_RecalcVolPan(&dsb->volpan);
+}
+
+static void DSOUND_Mix3DBuffer(IDirectSoundBufferImpl *dsb)
+{
+ TRACE("(%p)\n",dsb);
+
+ DSOUND_Calc3DBuffer(dsb);
+ DSOUND_ForceRemix(dsb);
+}
+
+static void WINAPI DSOUND_ChangeListener(IDirectSound3DListenerImpl *ds3dl)
+{
+ int i;
+ TRACE("(%p)\n",ds3dl);
+ for (i = 0; i < ds3dl->dsound->nrofbuffers; i++)
+ {
+ /* some buffers don't have 3d buffer (Ultima IX seems to
+ crash without the following line) */
+ if (ds3dl->dsound->buffers[i]->ds3db == NULL)
+ continue;
+ if (ds3dl->dsound->buffers[i]->ds3db_need_recalc == TRUE)
+ {
+ DSOUND_Mix3DBuffer(ds3dl->dsound->buffers[i]);
+ }
+ }
+}
+
+/*******************************************************************************
+ * 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);
+ 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;
+}
+
+static ULONG WINAPI IDirectSound3DBufferImpl_Release(LPDIRECTSOUND3DBUFFER iface)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ ULONG ulReturn;
+
+ TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+ if (!ulReturn) {
+ This->dsb->ds3db = NULL;
+ IDirectSoundBuffer_Release((LPDIRECTSOUNDBUFFER8)This->dsb);
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+
+ return ulReturn;
+}
+
+/* IDirectSound3DBuffer methods */
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetAllParameters(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPDS3DBUFFER lpDs3dBuffer)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("(%p,%p)\n",This,lpDs3dBuffer);
+
+ if (lpDs3dBuffer == NULL) {
+ WARN("invalid parameter: lpDs3dBuffer == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (lpDs3dBuffer->dwSize < sizeof(*lpDs3dBuffer)) {
+ WARN("invalid parameter: lpDs3dBuffer->dwSize = %ld < %d\n",lpDs3dBuffer->dwSize, sizeof(*lpDs3dBuffer));
+ return DSERR_INVALIDPARAM;
+ }
+
+ TRACE("returning: all parameters\n");
+ *lpDs3dBuffer = This->dsb->ds3db_ds3db;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeAngles(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPDWORD lpdwInsideConeAngle,
+ LPDWORD lpdwOutsideConeAngle)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ 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;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOrientation(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPD3DVECTOR lpvConeOrientation)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Cone Orientation vector = (%f,%f,%f)\n",
+ This->dsb->ds3db_ds3db.vConeOrientation.x,
+ This->dsb->ds3db_ds3db.vConeOrientation.y,
+ This->dsb->ds3db_ds3db.vConeOrientation.z);
+ *lpvConeOrientation = This->dsb->ds3db_ds3db.vConeOrientation;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetConeOutsideVolume(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPLONG lplConeOutsideVolume)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Cone Outside Volume = %ld\n", This->dsb->ds3db_ds3db.lConeOutsideVolume);
+ *lplConeOutsideVolume = This->dsb->ds3db_ds3db.lConeOutsideVolume;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetMaxDistance(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPD3DVALUE lpfMaxDistance)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Max Distance = %f\n", This->dsb->ds3db_ds3db.flMaxDistance);
+ *lpfMaxDistance = This->dsb->ds3db_ds3db.flMaxDistance;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetMinDistance(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPD3DVALUE lpfMinDistance)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Min Distance = %f\n", This->dsb->ds3db_ds3db.flMinDistance);
+ *lpfMinDistance = This->dsb->ds3db_ds3db.flMinDistance;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetMode(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPDWORD lpdwMode)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Mode = %ld\n", This->dsb->ds3db_ds3db.dwMode);
+ *lpdwMode = This->dsb->ds3db_ds3db.dwMode;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetPosition(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPD3DVECTOR lpvPosition)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Position vector = (%f,%f,%f)\n",
+ This->dsb->ds3db_ds3db.vPosition.x,
+ This->dsb->ds3db_ds3db.vPosition.y,
+ This->dsb->ds3db_ds3db.vPosition.z);
+ *lpvPosition = This->dsb->ds3db_ds3db.vPosition;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_GetVelocity(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPD3DVECTOR lpvVelocity)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("returning: Velocity vector = (%f,%f,%f)\n",
+ This->dsb->ds3db_ds3db.vVelocity.x,
+ This->dsb->ds3db_ds3db.vVelocity.y,
+ This->dsb->ds3db_ds3db.vVelocity.z);
+ *lpvVelocity = This->dsb->ds3db_ds3db.vVelocity;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetAllParameters(
+ LPDIRECTSOUND3DBUFFER iface,
+ LPCDS3DBUFFER lpcDs3dBuffer,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ DWORD status = DSERR_INVALIDPARAM;
+ TRACE("(%p,%p,%lx)\n",iface,lpcDs3dBuffer,dwApply);
+
+ if (lpcDs3dBuffer == NULL) {
+ WARN("invalid parameter: lpcDs3dBuffer == NULL\n");
+ return status;
+ }
+
+ if (lpcDs3dBuffer->dwSize != sizeof(DS3DBUFFER)) {
+ WARN("invalid parameter: lpcDs3dBuffer->dwSize = %ld != %d\n",
+ lpcDs3dBuffer->dwSize, sizeof(DS3DBUFFER));
+ return status;
+ }
+
+ 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;
+
+ return status;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeAngles(
+ LPDIRECTSOUND3DBUFFER iface,
+ DWORD dwInsideConeAngle,
+ DWORD dwOutsideConeAngle,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: Inside Cone Angle = %ld; Outside Cone Angle = %ld; dwApply = %ld\n",
+ dwInsideConeAngle, dwOutsideConeAngle, dwApply);
+ 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;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOrientation(
+ LPDIRECTSOUND3DBUFFER iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: Cone Orientation vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
+ This->dsb->ds3db_ds3db.vConeOrientation.x = x;
+ This->dsb->ds3db_ds3db.vConeOrientation.y = y;
+ This->dsb->ds3db_ds3db.vConeOrientation.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsb->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This->dsb);
+ }
+ This->dsb->ds3db_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetConeOutsideVolume(
+ LPDIRECTSOUND3DBUFFER iface,
+ LONG lConeOutsideVolume,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: ConeOutsideVolume = %ld; dwApply = %ld\n", lConeOutsideVolume, dwApply);
+ 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;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetMaxDistance(
+ LPDIRECTSOUND3DBUFFER iface,
+ D3DVALUE fMaxDistance,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: MaxDistance = %f; dwApply = %ld\n", fMaxDistance, dwApply);
+ 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;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetMinDistance(
+ LPDIRECTSOUND3DBUFFER iface,
+ D3DVALUE fMinDistance,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: MinDistance = %f; dwApply = %ld\n", fMinDistance, dwApply);
+ 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;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetMode(
+ LPDIRECTSOUND3DBUFFER iface,
+ DWORD dwMode,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: Mode = %ld; dwApply = %ld\n", dwMode, dwApply);
+ 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;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetPosition(
+ LPDIRECTSOUND3DBUFFER iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: Position vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
+ This->dsb->ds3db_ds3db.vPosition.x = x;
+ This->dsb->ds3db_ds3db.vPosition.y = y;
+ This->dsb->ds3db_ds3db.vPosition.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsb->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This->dsb);
+ }
+ This->dsb->ds3db_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DBufferImpl_SetVelocity(
+ LPDIRECTSOUND3DBUFFER iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DBufferImpl,iface);
+ TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
+ This->dsb->ds3db_ds3db.vVelocity.x = x;
+ This->dsb->ds3db_ds3db.vVelocity.y = y;
+ This->dsb->ds3db_ds3db.vVelocity.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsb->ds3db_need_recalc = FALSE;
+ DSOUND_Mix3DBuffer(This->dsb);
+ }
+ This->dsb->ds3db_need_recalc = TRUE;
+ 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 *dsb,
+ IDirectSound3DBufferImpl **pds3db)
+{
+ IDirectSound3DBufferImpl *ds3db;
+ TRACE("(%p,%p)\n",dsb,pds3db);
+
+ ds3db = (IDirectSound3DBufferImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*ds3db));
+
+ if (ds3db == NULL) {
+ WARN("out of memory\n");
+ *pds3db = 0;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ ds3db->ref = 0;
+ ds3db->dsb = dsb;
+ ds3db->lpVtbl = &ds3dbvt;
+
+ ds3db->dsb->ds3db_ds3db.dwSize = sizeof(DS3DBUFFER);
+ ds3db->dsb->ds3db_ds3db.vPosition.x = 0.0;
+ ds3db->dsb->ds3db_ds3db.vPosition.y = 0.0;
+ ds3db->dsb->ds3db_ds3db.vPosition.z = 0.0;
+ ds3db->dsb->ds3db_ds3db.vVelocity.x = 0.0;
+ ds3db->dsb->ds3db_ds3db.vVelocity.y = 0.0;
+ ds3db->dsb->ds3db_ds3db.vVelocity.z = 0.0;
+ ds3db->dsb->ds3db_ds3db.dwInsideConeAngle = DS3D_DEFAULTCONEANGLE;
+ ds3db->dsb->ds3db_ds3db.dwOutsideConeAngle = DS3D_DEFAULTCONEANGLE;
+ ds3db->dsb->ds3db_ds3db.vConeOrientation.x = 0.0;
+ ds3db->dsb->ds3db_ds3db.vConeOrientation.y = 0.0;
+ ds3db->dsb->ds3db_ds3db.vConeOrientation.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;
+
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER8)dsb);
+
+ *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);
+
+ if (ppobj == NULL) {
+ WARN("invalid parameter\n");
+ return E_INVALIDARG;
+ }
+
+ *ppobj = NULL; /* assume failure */
+
+ if ( IsEqualGUID(riid, &IID_IUnknown) ||
+ IsEqualGUID(riid, &IID_IDirectSound3DListener ) ) {
+ IDirectSound3DListener_AddRef((LPDIRECTSOUND3DLISTENER)This);
+ *ppobj = This;
+ return S_OK;
+ }
+
+ if ( IsEqualGUID(riid, &IID_IDirectSoundBuffer) ) {
+ if (!This->dsound->primary)
+ PrimaryBufferImpl_Create(This->dsound, &(This->dsound->primary), &(This->dsound->dsbd));
+ if (This->dsound->primary) {
+ *ppobj = This->dsound->primary;
+ IDirectSoundBuffer_AddRef((LPDIRECTSOUNDBUFFER)*ppobj);
+ return S_OK;
+ }
+ }
+
+ FIXME( "Unknown IID %s\n", debugstr_guid( riid ) );
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI IDirectSound3DListenerImpl_AddRef(LPDIRECTSOUND3DLISTENER iface)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ 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;
+}
+
+static ULONG WINAPI IDirectSound3DListenerImpl_Release(LPDIRECTSOUND3DLISTENER iface)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ ULONG ulReturn;
+
+ TRACE("(%p) ref was %ld, thread is %04lx\n",This, This->ref, GetCurrentThreadId());
+ ulReturn = InterlockedDecrement(&This->ref);
+
+ /* Free all resources */
+ if( ulReturn == 0 ) {
+ IDirectSound8_Release((LPDIRECTSOUND8)This->dsound);
+ This->dsound->listener = 0;
+ HeapFree(GetProcessHeap(),0,This);
+ TRACE("(%p) released\n",This);
+ }
+
+ return ulReturn;
+}
+
+/* IDirectSound3DListener methods */
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetAllParameter(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPDS3DLISTENER lpDS3DL)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("(%p,%p)\n",This,lpDS3DL);
+
+ if (lpDS3DL == NULL) {
+ WARN("invalid parameter: lpDS3DL == NULL\n");
+ return DSERR_INVALIDPARAM;
+ }
+
+ if (lpDS3DL->dwSize < sizeof(*lpDS3DL)) {
+ WARN("invalid parameter: lpDS3DL->dwSize = %ld < %d\n",lpDS3DL->dwSize, sizeof(*lpDS3DL));
+ return DSERR_INVALIDPARAM;
+ }
+
+ TRACE("returning: all parameters\n");
+ *lpDS3DL = This->dsound->ds3dl;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetDistanceFactor(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPD3DVALUE lpfDistanceFactor)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("returning: Distance Factor = %f\n", This->dsound->ds3dl.flDistanceFactor);
+ *lpfDistanceFactor = This->dsound->ds3dl.flDistanceFactor;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetDopplerFactor(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPD3DVALUE lpfDopplerFactor)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("returning: Doppler Factor = %f\n", This->dsound->ds3dl.flDopplerFactor);
+ *lpfDopplerFactor = This->dsound->ds3dl.flDopplerFactor;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetOrientation(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPD3DVECTOR lpvOrientFront,
+ LPD3DVECTOR lpvOrientTop)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("returning: OrientFront vector = (%f,%f,%f); OrientTop vector = (%f,%f,%f)\n", This->dsound->ds3dl.vOrientFront.x, \
+ This->dsound->ds3dl.vOrientFront.y, This->dsound->ds3dl.vOrientFront.z, This->dsound->ds3dl.vOrientTop.x, This->dsound->ds3dl.vOrientTop.y, \
+ This->dsound->ds3dl.vOrientTop.z);
+ *lpvOrientFront = This->dsound->ds3dl.vOrientFront;
+ *lpvOrientTop = This->dsound->ds3dl.vOrientTop;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetPosition(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPD3DVECTOR lpvPosition)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("returning: Position vector = (%f,%f,%f)\n", This->dsound->ds3dl.vPosition.x, This->dsound->ds3dl.vPosition.y, This->dsound->ds3dl.vPosition.z);
+ *lpvPosition = This->dsound->ds3dl.vPosition;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetRolloffFactor(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPD3DVALUE lpfRolloffFactor)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("returning: RolloffFactor = %f\n", This->dsound->ds3dl.flRolloffFactor);
+ *lpfRolloffFactor = This->dsound->ds3dl.flRolloffFactor;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_GetVelocity(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPD3DVECTOR lpvVelocity)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("returning: Velocity vector = (%f,%f,%f)\n", This->dsound->ds3dl.vVelocity.x, This->dsound->ds3dl.vVelocity.y, This->dsound->ds3dl.vVelocity.z);
+ *lpvVelocity = This->dsound->ds3dl.vVelocity;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetAllParameters(
+ LPDIRECTSOUND3DLISTENER iface,
+ LPCDS3DLISTENER lpcDS3DL,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("setting: all parameters; dwApply = %ld\n", dwApply);
+ This->dsound->ds3dl = *lpcDS3DL;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetDistanceFactor(
+ LPDIRECTSOUND3DLISTENER iface,
+ D3DVALUE fDistanceFactor,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("setting: Distance Factor = %f; dwApply = %ld\n", fDistanceFactor, dwApply);
+ This->dsound->ds3dl.flDistanceFactor = fDistanceFactor;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetDopplerFactor(
+ LPDIRECTSOUND3DLISTENER iface,
+ D3DVALUE fDopplerFactor,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("setting: Doppler Factor = %f; dwApply = %ld\n", fDopplerFactor, dwApply);
+ This->dsound->ds3dl.flDopplerFactor = fDopplerFactor;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetOrientation(
+ LPDIRECTSOUND3DLISTENER iface,
+ D3DVALUE xFront, D3DVALUE yFront, D3DVALUE zFront,
+ D3DVALUE xTop, D3DVALUE yTop, D3DVALUE zTop,
+ DWORD dwApply)
+{
+ 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);
+ This->dsound->ds3dl.vOrientFront.x = xFront;
+ This->dsound->ds3dl.vOrientFront.y = yFront;
+ This->dsound->ds3dl.vOrientFront.z = zFront;
+ This->dsound->ds3dl.vOrientTop.x = xTop;
+ This->dsound->ds3dl.vOrientTop.y = yTop;
+ This->dsound->ds3dl.vOrientTop.z = zTop;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetPosition(
+ LPDIRECTSOUND3DLISTENER iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("setting: Position vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
+ This->dsound->ds3dl.vPosition.x = x;
+ This->dsound->ds3dl.vPosition.y = y;
+ This->dsound->ds3dl.vPosition.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetRolloffFactor(
+ LPDIRECTSOUND3DLISTENER iface,
+ D3DVALUE fRolloffFactor,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("setting: Rolloff Factor = %f; dwApply = %ld\n", fRolloffFactor, dwApply);
+ This->dsound->ds3dl.flRolloffFactor = fRolloffFactor;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_SetVelocity(
+ LPDIRECTSOUND3DLISTENER iface,
+ D3DVALUE x, D3DVALUE y, D3DVALUE z,
+ DWORD dwApply)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("setting: Velocity vector = (%f,%f,%f); dwApply = %ld\n", x, y, z, dwApply);
+ This->dsound->ds3dl.vVelocity.x = x;
+ This->dsound->ds3dl.vVelocity.y = y;
+ This->dsound->ds3dl.vVelocity.z = z;
+ if (dwApply == DS3D_IMMEDIATE)
+ {
+ This->dsound->ds3dl_need_recalc = FALSE;
+ DSOUND_ChangeListener(This);
+ }
+ This->dsound->ds3dl_need_recalc = TRUE;
+ return DS_OK;
+}
+
+static HRESULT WINAPI IDirectSound3DListenerImpl_CommitDeferredSettings(
+ LPDIRECTSOUND3DLISTENER iface)
+{
+ ICOM_THIS(IDirectSound3DListenerImpl,iface);
+ TRACE("\n");
+ DSOUND_ChangeListener(This);
+ 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;
+ TRACE("(%p,%p)\n",This,pdsl);
+
+ dsl = (IDirectSound3DListenerImpl*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(*dsl));
+
+ if (dsl == NULL) {
+ WARN("out of memory\n");
+ *pdsl = 0;
+ return DSERR_OUTOFMEMORY;
+ }
+
+ dsl->ref = 0;
+ dsl->lpVtbl = &ds3dlvt;
+
+ dsl->dsound = This->dsound;
+
+ dsl->dsound->ds3dl.dwSize = sizeof(DS3DLISTENER);
+ dsl->dsound->ds3dl.vPosition.x = 0.0;
+ dsl->dsound->ds3dl.vPosition.y = 0.0;
+ dsl->dsound->ds3dl.vPosition.z = 0.0;
+ dsl->dsound->ds3dl.vVelocity.x = 0.0;
+ dsl->dsound->ds3dl.vVelocity.y = 0.0;
+ dsl->dsound->ds3dl.vVelocity.z = 0.0;
+ dsl->dsound->ds3dl.vOrientFront.x = 0.0;
+ dsl->dsound->ds3dl.vOrientFront.y = 0.0;
+ dsl->dsound->ds3dl.vOrientFront.z = 1.0;
+ dsl->dsound->ds3dl.vOrientTop.x = 0.0;
+ dsl->dsound->ds3dl.vOrientTop.y = 1.0;
+ dsl->dsound->ds3dl.vOrientTop.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;
+
+ IDirectSound8_AddRef((LPDIRECTSOUND8)This->dsound);
+
+ *pdsl = dsl;
+ return S_OK;
+}
Binary files dlls/dsound/sound3d.o and /home/wine/wine.save6/dlls/dsound/sound3d.o differ
Common subdirectories: dlls/dsound/tests and /home/wine/wine.save6/dlls/dsound/tests
Only in dlls/dsound: trace
diff -u --unidirectional-new-file dlls/dsound/version.rc /home/wine/wine.save6/dlls/dsound/version.rc
--- dlls/dsound/version.rc 2004-05-29 18:35:41.000000000 -0400
+++ /home/wine/wine.save6/dlls/dsound/version.rc 2004-03-10 18:39:28.000000000 -0500
@@ -19,10 +19,10 @@
#define WINE_OLESELFREGISTER
#define WINE_FILEDESCRIPTION_STR "Wine DirectSound"
#define WINE_FILENAME_STR "dsound.dll"
-#define WINE_FILEVERSION 5,3,0,900
-#define WINE_FILEVERSION_STR "5.3.0.900"
-#define WINE_PRODUCTVERSION 5,3,0,900
-#define WINE_PRODUCTVERSION_STR "5.3"
+#define WINE_FILEVERSION 4,8,1,881
+#define WINE_FILEVERSION_STR "4.8.1.881"
+#define WINE_PRODUCTVERSION 4,8,1,881
+#define WINE_PRODUCTVERSION_STR "4.8"
#define WINE_PRODUCTNAME_STR "DirectX"
#include "wine/wine_common_ver.rc"
Binary files dlls/dsound/version.res and /home/wine/wine.save6/dlls/dsound/version.res differ
More information about the wine-patches
mailing list