Implement SetLoopRegion and SetPlayRegion Support

WaveBank Sample now play audio 100% correctly, can't verify with other
sound samples.
Audio do sound a bit better to me.

Some titles are still not getting all audio outputting for some reason.
However, it did brought more audible outputs now.

NOTE: It is still "somewhat" leaving experimental stage.
This commit is contained in:
RadWolfie 2017-10-28 02:34:32 -05:00
parent 7fc65b57ce
commit c9ebe3ed18
3 changed files with 416 additions and 210 deletions

View File

@ -397,10 +397,11 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)()
LOG_FUNC();
//TODO: This need a lock in each frame. I think it does not wait for each frame.
// Bypass Update buffer, audio appear to be working just fine without need to update audio.
/*
XTL::X_CDirectSoundBuffer* *pDSBuffer = g_pDSoundBufferCache;
for (int v = 0; v < SOUNDBUFFER_CACHE_SIZE; v++, pDSBuffer++) {
if ((*pDSBuffer) == nullptr || (*pDSBuffer)->EmuBuffer == nullptr) {
if ((*pDSBuffer) == nullptr || (*pDSBuffer)->EmuBuffer == nullptr || (*pDSBuffer)->EmuBufferToggle != X_DSB_TOGGLE_DEFAULT) {
continue;
}
DSoundBufferUpdate((*pDSBuffer)->EmuDirectSoundBuffer8,
@ -431,7 +432,7 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)()
(*pDSStream)->EmuLockBytes2,
0);
}
*/
leaveCriticalSection;
return;
@ -804,7 +805,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer)
DWORD dwEmuFlags = 0;
DSBUFFERDESC *pDSBufferDesc = (DSBUFFERDESC*)g_MemoryManager.Allocate(sizeof(DSBUFFERDESC));
DSBUFFERDESC *pDSBufferDesc = (DSBUFFERDESC*)malloc(sizeof(DSBUFFERDESC));
//DWORD dwAcceptableMask = 0x00000010 | 0x00000020 | 0x00000080 | 0x00000100 | 0x00002000 | 0x00040000 | 0x00080000;
DWORD dwAcceptableMask = 0x00000010 | 0x00000020 | 0x00000080 | 0x00000100 | 0x00020000 | 0x00040000 /*| 0x00080000*/;
@ -816,48 +817,22 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer)
pDSBufferDesc->dwSize = sizeof(DSBUFFERDESC);
pDSBufferDesc->dwFlags = (pdsbd->dwFlags & dwAcceptableMask) | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLFREQUENCY;
pDSBufferDesc->dwBufferBytes = pdsbd->dwBufferBytes;
pDSBufferDesc->lpwfxFormat = nullptr;
GeneratePCMFormat(pDSBufferDesc, pdsbd->lpwfxFormat, dwEmuFlags);
// TODO: Garbage Collection
*ppBuffer = new X_CDirectSoundBuffer();
(*ppBuffer)->EmuDirectSoundBuffer8 = nullptr;
(*ppBuffer)->EmuDirectSound3DBuffer8 = nullptr;
(*ppBuffer)->EmuBuffer = xbnullptr;
(*ppBuffer)->EmuBufferDesc = pDSBufferDesc;
DSoundBufferSetDefault((*ppBuffer), pDSBufferDesc, dwEmuFlags, 0);
(*ppBuffer)->EmuLockOffset = 0;
(*ppBuffer)->EmuLockPtr1 = xbnullptr;
(*ppBuffer)->EmuLockBytes1 = 0;
(*ppBuffer)->EmuLockPtr2 = xbnullptr;
(*ppBuffer)->EmuLockBytes2 = 0;
(*ppBuffer)->EmuFlags = dwEmuFlags;
DSoundBufferRegionSetDefault(*ppBuffer);
DbgPrintf("EmuDSound: DirectSoundCreateBuffer, *ppBuffer := 0x%.08X, bytes := 0x%.08X\n", *ppBuffer, pDSBufferDesc->dwBufferBytes);
//Temporary creation since we need IDIRECTSOUNDBUFFER8, not IDIRECTSOUNDBUFFER class.
LPDIRECTSOUNDBUFFER pTempBuffer;
HRESULT hRet = g_pDSound8->CreateSoundBuffer(pDSBufferDesc, &pTempBuffer, NULL);
if (hRet != DS_OK) {
CxbxKrnlCleanup("CreateSoundBuffer Failed!");
(*ppBuffer)->EmuDirectSoundBuffer8 = nullptr;
} else {
hRet = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&((*ppBuffer)->EmuDirectSoundBuffer8));
pTempBuffer->Release();
if (hRet != DS_OK) {
CxbxKrnlCleanup("CreateSoundBuffer8 Failed!");
}
if (pdsbd->dwFlags & DSBCAPS_CTRL3D) {
HRESULT hRet3D = (*ppBuffer)->EmuDirectSoundBuffer8->QueryInterface(IID_IDirectSound3DBuffer8, (LPVOID*)&((*ppBuffer)->EmuDirectSound3DBuffer8));
if (hRet3D != DS_OK) {
EmuWarning("CreateSound3DBuffer8 Failed!");
(*ppBuffer)->EmuDirectSound3DBuffer8 = nullptr;
}
}
DSoundBufferCreate(pDSBufferDesc, (*ppBuffer)->EmuDirectSoundBuffer8);
if (pdsbd->dwFlags & DSBCAPS_CTRL3D) {
DSound3DBufferCreate((*ppBuffer)->EmuDirectSoundBuffer8, (*ppBuffer)->EmuDirectSound3DBuffer8);
}
// cache this sound buffer
@ -926,12 +901,20 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData)
leaveCriticalSection;
return DS_OK;
}
ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuPlayFlags, dwBufferBytes, pThis->EmuDirectSound3DBuffer8);
ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuPlayFlags, dwBufferBytes, pThis->EmuDirectSound3DBuffer8);
DSoundBufferRegionRelease(pThis);
XTL::EMUPATCH(IDirectSoundBuffer_Lock)(pThis, 0, dwBufferBytes, &pThis->EmuLockPtr1, &pThis->EmuLockBytes1, NULL, NULL, pThis->EmuLockFlags);
if (pThis->EmuLockPtr1 != 0) {
memcpy(pThis->EmuLockPtr1, pvBufferData, pThis->EmuLockBytes1);
// TODO: We could reduce allocate and free buffer if the size is the same.
if (pThis->EmuBuffer != xbnullptr) {
free(pThis->EmuBuffer);
}
pThis->EmuBuffer = malloc(dwBufferBytes);
memcpy(pThis->EmuBuffer, pvBufferData, dwBufferBytes);
}
DSoundGenericUnlock(pThis->EmuFlags,
@ -968,14 +951,12 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPlayRegion)
LOG_FUNC_ARG(dwPlayLength)
LOG_FUNC_END;
// TODO: Translate params, then make the PC DirectSound call
// TODO: Ensure that 4627 & 4361 are intercepting far enough back
// (otherwise pThis is manipulated!)
// pThis->EmuDirectSoundBuffer8->SetCurrentPosition(dwPlayStart);
LOG_UNIMPLEMENTED_DSOUND();
pThis->EmuBufferToggle = X_DSB_TOGGLE_PLAY;
pThis->EmuRegionPlayStartOffset = dwPlayStart;
pThis->EmuRegionPlayLength = dwPlayLength;
leaveCriticalSection;
@ -1014,7 +995,12 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Lock)
HRESULT hRet = D3D_OK;
if (dwBytes > pThis->EmuBufferDesc->dwBufferBytes) {
if (pThis->EmuBuffer != nullptr) {
free(pThis->EmuBuffer);
pThis->EmuBuffer = nullptr;
}
ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuPlayFlags, dwBytes, pThis->EmuDirectSound3DBuffer8);
DSoundBufferRegionRelease(pThis);
}
DSoundGenericUnlock(pThis->EmuFlags,
@ -1068,6 +1054,13 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Unlock)
LOG_FUNC_ARG(pdwAudioBytes2)
LOG_FUNC_END;
if (pThis->EmuBuffer != xbnullptr) {
memcpy_s((PBYTE)pThis->EmuBuffer + pThis->EmuLockOffset,
pThis->EmuBufferDesc->dwBufferBytes - pThis->EmuLockOffset,
pThis->EmuLockPtr1,
pThis->EmuLockBytes1);
}
DSoundGenericUnlock(pThis->EmuFlags,
pThis->EmuDirectSoundBuffer8,
pThis->EmuBufferDesc,
@ -1130,8 +1123,10 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetLoopRegion)
// TODO: Ensure that 4627 & 4361 are intercepting far enough back
// (otherwise pThis is manipulated!)
//ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuPlayFlags, dwLoopLength);
LOG_UNIMPLEMENTED_DSOUND();
pThis->EmuRegionLoopStartOffset = pThis->EmuRegionPlayStartOffset + dwLoopStart;
pThis->EmuRegionLoopStartOffset = dwLoopStart;
pThis->EmuRegionLoopLength = dwLoopLength;
pThis->EmuBufferToggle = X_DSB_TOGGLE_LOOP;
leaveCriticalSection;
@ -1153,13 +1148,12 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release)
ULONG uRet = 0;
//TODO: RadWolfie - Need to move them into inline release function.
if (pThis != 0) {
if (!(pThis->EmuFlags & DSB_FLAG_RECIEVEDATA)) {
uRet = pThis->EmuDirectSoundBuffer8->Release();
if (uRet == 0) {
if (pThis->EmuDirectSound3DBuffer8 != NULL) {
if (pThis->EmuDirectSound3DBuffer8 != nullptr) {
pThis->EmuDirectSound3DBuffer8->Release();
}
// remove cache entry
@ -1169,11 +1163,19 @@ ULONG WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Release)
}
}
if (pThis->EmuBufferDesc->lpwfxFormat != NULL) {
g_MemoryManager.Free(pThis->EmuBufferDesc->lpwfxFormat);
if (pThis->EmuBufferDesc->lpwfxFormat != nullptr) {
free(pThis->EmuBufferDesc->lpwfxFormat);
}
g_MemoryManager.Free(pThis->EmuBufferDesc);
if (pThis->EmuBuffer != xbnullptr) {
free(pThis->EmuBuffer);
}
if (pThis->EmuDirectSoundBuffer8Region != nullptr) {
pThis->EmuDirectSoundBuffer8Region->Release();
}
if (pThis->EmuDirectSound3DBuffer8Region != nullptr) {
pThis->EmuDirectSound3DBuffer8Region->Release();
}
free(pThis->EmuBufferDesc);
delete pThis;
}
@ -1200,7 +1202,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPitch)
LOG_FUNC_ARG(lPitch)
LOG_FUNC_END;
return HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch);
return HybridDirectSoundBuffer_SetPitch(DSoundBufferSelectionT(pThis), lPitch);
}
// ******************************************************************
@ -1218,7 +1220,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetStatus)
LOG_FUNC_ARG_OUT(pdwStatus)
LOG_FUNC_END;
return HybridDirectSoundBuffer_GetStatus(pThis->EmuDirectSoundBuffer8, pdwStatus);
return HybridDirectSoundBuffer_GetStatus(DSoundBufferSelectionT(pThis), pdwStatus);
}
// ******************************************************************
@ -1267,7 +1269,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_GetCurrentPosition)
LOG_FUNC_ARG_OUT(pdwCurrentWriteCursor)
LOG_FUNC_END;
return HybridDirectSoundBuffer_GetCurrentPosition(pThis->EmuDirectSoundBuffer8, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
return HybridDirectSoundBuffer_GetCurrentPosition(DSoundBufferSelectionT(pThis), pdwCurrentPlayCursor, pdwCurrentWriteCursor);
}
// ******************************************************************
@ -1301,13 +1303,83 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play)
pThis->EmuLockBytes2,
pThis->EmuLockFlags);
if (dwFlags & ~(X_DSBPLAY_LOOPING | X_DSBPLAY_FROMSTART | X_DSBPLAY_SYNCHPLAYBACK)) {
CxbxKrnlCleanup("Unsupported Playing Flags");
}
pThis->EmuPlayFlags = dwFlags;
HRESULT hRet = HybridDirectSoundBuffer_Play(pThis->EmuDirectSoundBuffer8, pThis->EmuPlayFlags, pThis->EmuFlags);
// rewind buffer
if ((dwFlags & X_DSBPLAY_FROMSTART)) {
pThis->EmuPlayFlags &= ~X_DSBPLAY_FROMSTART;
}
if (dwFlags & X_DSBPLAY_SYNCHPLAYBACK) {
pThis->EmuPlayFlags ^= X_DSBPLAY_SYNCHPLAYBACK;
pThis->EmuFlags |= DSB_FLAG_SYNCHPLAYBACK_CONTROL;
}
HRESULT hRet = DS_OK;
// Process Play/Loop Region buffer (Region Buffer creation can be only place inside Play function
if (pThis->EmuDirectSoundBuffer8Region == nullptr && pThis->EmuBufferToggle != X_DSB_TOGGLE_DEFAULT) {
DWORD byteLength;
DWORD startOffset;
LPDSBUFFERDESC emuBufferDescRegion = (LPDSBUFFERDESC)malloc(sizeof(DSBUFFERDESC));
memcpy_s(emuBufferDescRegion, sizeof(DSBUFFERDESC), pThis->EmuBufferDesc, sizeof(DSBUFFERDESC));
switch (pThis->EmuBufferToggle) {
case X_DSB_TOGGLE_LOOP:
if (pThis->EmuRegionLoopLength == 0) {
byteLength = pThis->EmuRegionPlayLength;
} else {
byteLength = pThis->EmuRegionLoopLength;
}
startOffset = pThis->EmuRegionPlayStartOffset + pThis->EmuRegionLoopStartOffset;
break;
case X_DSB_TOGGLE_PLAY:
byteLength = pThis->EmuRegionPlayLength;
startOffset = pThis->EmuRegionPlayStartOffset;
break;
default:
free(emuBufferDescRegion);
CxbxKrnlCleanup("Unknown TOGGLE region for DirectSoundBuffer class usage.");
}
emuBufferDescRegion->dwBufferBytes = byteLength;
DSoundBufferCreate(emuBufferDescRegion, pThis->EmuDirectSoundBuffer8Region);
if (pThis->EmuDirectSound3DBuffer8 != nullptr) {
DSound3DBufferCreate(pThis->EmuDirectSoundBuffer8, pThis->EmuDirectSound3DBuffer8Region);
}
DSoundBufferTransfer(pThis->EmuDirectSoundBuffer8, pThis->EmuDirectSoundBuffer8Region,
pThis->EmuDirectSound3DBuffer8, pThis->EmuDirectSound3DBuffer8Region);
hRet = pThis->EmuDirectSoundBuffer8Region->Lock(0, 0, &pThis->EmuLockPtr1, &pThis->EmuLockBytes1, nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
if (hRet != DS_OK) {
CxbxKrnlCleanup("Unable to lock region buffer!");
}
if (pThis->EmuLockPtr1 != nullptr) {
memcpy_s(pThis->EmuLockPtr1, pThis->EmuLockBytes1, (PVOID)((PBYTE)pThis->EmuBuffer + startOffset), byteLength);
if (pThis->EmuFlags & DSB_FLAG_XADPCM) {
DSoundBufferXboxAdpcmDecoder(pThis->EmuDirectSoundBuffer8Region, emuBufferDescRegion, 0, pThis->EmuLockPtr1, pThis->EmuLockBytes1, nullptr, 0, true);
}
pThis->EmuDirectSoundBuffer8Region->Unlock(pThis->EmuLockPtr1, pThis->EmuLockBytes1, nullptr, 0);
}
free(emuBufferDescRegion);
}
if (dwFlags & X_DSBPLAY_FROMSTART) {
if (DSoundBufferSelectionT(pThis)->SetCurrentPosition(0) != DS_OK) {
EmuWarning("Rewinding buffer failed!");
}
}
if ((pThis->EmuFlags & DSB_FLAG_SYNCHPLAYBACK_CONTROL) == 0) {
hRet = DSoundBufferSelectionT(pThis)->Play(0, 0, pThis->EmuPlayFlags);
}
leaveCriticalSection;
return hRet;
RETURN_RESULT_CHECK(hRet);
}
// ******************************************************************
@ -1325,10 +1397,16 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Stop)
HRESULT hRet = D3D_OK;
if (pThis != nullptr && pThis->EmuDirectSoundBuffer8 != nullptr) {
// TODO : Test Stop (emulated via Stop + SetCurrentPosition(0)) :
hRet = pThis->EmuDirectSoundBuffer8->Stop();
pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0);
if (pThis != nullptr) {
if (pThis->EmuDirectSoundBuffer8Region != nullptr) {
// TODO : Test Stop (emulated via Stop + SetCurrentPosition(0)) :
hRet = pThis->EmuDirectSoundBuffer8Region->Stop();
pThis->EmuDirectSoundBuffer8Region->SetCurrentPosition(0);
} else if (pThis->EmuDirectSoundBuffer8 != nullptr) {
// TODO : Test Stop (emulated via Stop + SetCurrentPosition(0)) :
hRet = pThis->EmuDirectSoundBuffer8->Stop();
pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0);
}
}
leaveCriticalSection;
@ -1358,10 +1436,43 @@ extern "C" HRESULT __stdcall XTL::EMUPATCH(IDirectSoundBuffer_StopEx)
HRESULT hRet = D3D_OK;
//TODO: RadWolfie - Rayman 3 crash at end of first intro for this issue... if only return DS_OK, then it works fine until end of 2nd intro it crashed.
if (pThis != nullptr && pThis->EmuDirectSoundBuffer8 != nullptr) {
if (pThis != nullptr) {
// TODO : Test Stop (emulated via Stop + SetCurrentPosition(0)) :
hRet = pThis->EmuDirectSoundBuffer8->Stop();
pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0);
switch (dwFlags) {
case X_DSBSTOPEX_IMMEDIATE:
hRet = DSoundBufferSelectionT(pThis)->Stop();
DSoundBufferSelectionT(pThis)->SetCurrentPosition(0);
break;
case X_DSBSTOPEX_ENVELOPE:
// TODO: How to mock up "release phase"?
break;
case X_DSBSTOPEX_RELEASEWAVEFORM:
// Release from loop region.
DWORD dwValue, dwStatus;
if (pThis->EmuDirectSoundBuffer8Region != nullptr) {
pThis->EmuDirectSoundBuffer8Region->GetStatus(&dwStatus);
DSoundBufferTransfer(pThis->EmuDirectSoundBuffer8Region, pThis->EmuDirectSoundBuffer8,
pThis->EmuDirectSound3DBuffer8Region, pThis->EmuDirectSound3DBuffer8);
hRet = pThis->EmuDirectSoundBuffer8Region->Stop();
pThis->EmuDirectSoundBuffer8Region->GetCurrentPosition(&dwValue, nullptr);
dwValue += pThis->EmuRegionLoopStartOffset + pThis->EmuRegionPlayStartOffset;
pThis->EmuDirectSoundBuffer8->SetCurrentPosition(dwValue);
if (dwStatus & DSBSTATUS_PLAYING) {
pThis->EmuDirectSoundBuffer8->Play(0, 0, pThis->EmuPlayFlags);
}
// Finally, release region buffer.
DSoundBufferRegionRelease(pThis);
}
// TODO: How to mock up "release phase"?
break;
default:
CxbxKrnlCleanup("Unknown dwFlags from IDirectSoundBuffer_StopEx: %8X", dwFlags);
}
}
leaveCriticalSection;
@ -1387,7 +1498,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVolume)
// TODO: Ensure that 4627 & 4361 are intercepting far enough back
// (otherwise pThis is manipulated!)
return HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags);
return HybridDirectSoundBuffer_SetVolume(DSoundBufferSelectionT(pThis), lVolume, pThis->EmuFlags);
}
// ******************************************************************
@ -1405,7 +1516,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFrequency)
LOG_FUNC_ARG(dwFrequency)
LOG_FUNC_END;
return HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency);
return HybridDirectSoundBuffer_SetFrequency(DSoundBufferSelectionT(pThis), dwFrequency);
}
// ******************************************************************
@ -1439,7 +1550,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
// TODO: Garbage Collection
*ppStream = new X_CDirectSoundStream();
DSBUFFERDESC *pDSBufferDesc = (DSBUFFERDESC*)g_MemoryManager.Allocate(sizeof(DSBUFFERDESC));
DSBUFFERDESC *pDSBufferDesc = (DSBUFFERDESC*)malloc(sizeof(DSBUFFERDESC));
DWORD dwAcceptableMask = 0x00000010; // TODO: Note 0x00040000 is being ignored (DSSTREAMCAPS_LOCDEFER)
@ -1451,20 +1562,11 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
//pDSBufferDesc->dwFlags = (pdssd->dwFlags & dwAcceptableMask) | DSBCAPS_CTRLVOLUME | DSBCAPS_GETCURRENTPOSITION2;
pDSBufferDesc->dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; //aka DSBCAPS_DEFAULT
pDSBufferDesc->dwBufferBytes = DSBSIZE_MIN;
pDSBufferDesc->lpwfxFormat = nullptr;
GeneratePCMFormat(pDSBufferDesc, pdssd->lpwfxFormat, dwEmuFlags);
(*ppStream)->EmuDirectSoundBuffer8 = nullptr;
(*ppStream)->EmuDirectSound3DBuffer8 = nullptr;
(*ppStream)->EmuBuffer = xbnullptr;
(*ppStream)->EmuBufferDesc = pDSBufferDesc;
(*ppStream)->EmuLockPtr1 = xbnullptr;
(*ppStream)->EmuLockBytes1 = 0;
(*ppStream)->EmuLockPtr2 = xbnullptr;
(*ppStream)->EmuLockBytes2 = 0;
(*ppStream)->EmuFlags = dwEmuFlags;
(*ppStream)->EmuPlayFlags = DSBPLAY_LOOPING;
DSoundBufferSetDefault((*ppStream), pDSBufferDesc, dwEmuFlags, DSBPLAY_LOOPING);
DbgPrintf("EmuDSound: DirectSoundCreateStream, *ppStream := 0x%.08X\n", *ppStream);
@ -1472,31 +1574,13 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
LPDIRECTSOUNDBUFFER pTempBuffer;
HRESULT hRet = g_pDSound8->CreateSoundBuffer(pDSBufferDesc, &pTempBuffer, NULL);
if (hRet != DS_OK) {
CxbxKrnlCleanup("CreateSoundBuffer Failed!");
(*ppStream)->EmuDirectSoundBuffer8 = nullptr;
} else {
hRet = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&((*ppStream)->EmuDirectSoundBuffer8));
pTempBuffer->Release();
if (hRet != DS_OK) {
CxbxKrnlCleanup("CreateSoundBuffer8 Failed!");
}
(*ppStream)->EmuDirectSoundBuffer8->SetCurrentPosition(0);
(*ppStream)->EmuDirectSoundBuffer8->Play(0, 0, DSBPLAY_LOOPING); //Apparently DirectSoundStream do not wait, let's go ahead start play "nothing".
if (pDSBufferDesc->dwFlags & DSBCAPS_CTRL3D) {
HRESULT hRet3D = (*ppStream)->EmuDirectSoundBuffer8->QueryInterface(IID_IDirectSound3DBuffer8, (LPVOID*)&((*ppStream)->EmuDirectSound3DBuffer8));
if (hRet3D != DS_OK) {
EmuWarning("CreateSound3DBuffer Failed!");
(*ppStream)->EmuDirectSound3DBuffer8 = nullptr;
}
}
DSoundBufferCreate(pDSBufferDesc, (*ppStream)->EmuDirectSoundBuffer8);
if (pDSBufferDesc->dwFlags & DSBCAPS_CTRL3D) {
DSound3DBufferCreate((*ppStream)->EmuDirectSoundBuffer8, (*ppStream)->EmuDirectSound3DBuffer8);
}
// __asm int 3
(*ppStream)->EmuDirectSoundBuffer8->SetCurrentPosition(0);
(*ppStream)->EmuDirectSoundBuffer8->Play(0, 0, DSBPLAY_LOOPING); //Apparently DirectSoundStream do not wait, let's go ahead start play "nothing".
// cache this sound stream
{
@ -1635,7 +1719,6 @@ ULONG WINAPI XTL::EMUPATCH(CDirectSoundStream_Release)
LOG_FUNC_ONE_ARG(pThis);
ULONG uRet = 0;
//TODO: RadWolfie - Need to move them into inline release function.
if (pThis != 0 && (pThis->EmuDirectSoundBuffer8 != 0)) {
uRet = pThis->EmuDirectSoundBuffer8->Release();
@ -1651,10 +1734,10 @@ ULONG WINAPI XTL::EMUPATCH(CDirectSoundStream_Release)
}
if (pThis->EmuBufferDesc->lpwfxFormat != NULL) {
g_MemoryManager.Free(pThis->EmuBufferDesc->lpwfxFormat);
free(pThis->EmuBufferDesc->lpwfxFormat);
}
g_MemoryManager.Free(pThis->EmuBufferDesc);
// NOTE: Do not release EmuBuffer! EmuBuffer is using xbox buffer.
free(pThis->EmuBufferDesc);
delete pThis;
}
@ -1734,7 +1817,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_Process)
LOG_FUNC_ARG(pOutputBuffer)
LOG_FUNC_END;
if (pThis->EmuDirectSoundBuffer8 != NULL) {
if (pThis->EmuDirectSoundBuffer8 != nullptr) {
// update buffer data cache
pThis->EmuBuffer = pInputBuffer->pvBuffer;
@ -1861,8 +1944,9 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSound_SynchPlayback)
}
if ((*pDSBuffer)->EmuFlags & DSB_FLAG_SYNCHPLAYBACK_CONTROL) {
(*pDSBuffer)->EmuDirectSoundBuffer8->SetCurrentPosition(0);
(*pDSBuffer)->EmuDirectSoundBuffer8->Play(0, 0, (*pDSBuffer)->EmuPlayFlags);
// RadWolfie: I don't think SetCurrentPosition is necessary?
//DSoundBufferSelectionT((*pDSBuffer))->SetCurrentPosition(0);
DSoundBufferSelectionT((*pDSBuffer))->Play(0, 0, (*pDSBuffer)->EmuPlayFlags);
(*pDSBuffer)->EmuFlags ^= DSB_FLAG_SYNCHPLAYBACK_CONTROL;
}
}
@ -2199,7 +2283,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMaxDistance)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetMaxDistance(pThis->EmuDirectSound3DBuffer8, flMaxDistance, dwApply);
return HybridDirectSound3DBuffer_SetMaxDistance(DSound3DBufferSelectionT(pThis), flMaxDistance, dwApply);
}
// ******************************************************************
@ -2219,7 +2303,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMinDistance)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetMinDistance(pThis->EmuDirectSound3DBuffer8, flMinDistance, dwApply);
return HybridDirectSound3DBuffer_SetMinDistance(DSound3DBufferSelectionT(pThis), flMinDistance, dwApply);
}
// ******************************************************************
@ -2293,7 +2377,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeAngles)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetConeAngles(pThis->EmuDirectSound3DBuffer8, dwInsideConeAngle, dwOutsideConeAngle, dwApply);
return HybridDirectSound3DBuffer_SetConeAngles(DSound3DBufferSelectionT(pThis), dwInsideConeAngle, dwOutsideConeAngle, dwApply);
}
// ******************************************************************
@ -2317,7 +2401,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOrientation)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetConeOrientation(pThis->EmuDirectSound3DBuffer8, x, y, z, dwApply);
return HybridDirectSound3DBuffer_SetConeOrientation(DSound3DBufferSelectionT(pThis), x, y, z, dwApply);
}
// ******************************************************************
@ -2337,7 +2421,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetConeOutsideVolume(pThis->EmuDirectSound3DBuffer8, lConeOutsideVolume, dwApply);
return HybridDirectSound3DBuffer_SetConeOutsideVolume(DSound3DBufferSelectionT(pThis), lConeOutsideVolume, dwApply);
}
// ******************************************************************
@ -2361,7 +2445,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetPosition)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetPosition(pThis->EmuDirectSound3DBuffer8, x, y, z, dwApply);
return HybridDirectSound3DBuffer_SetPosition(DSound3DBufferSelectionT(pThis), x, y, z, dwApply);
}
// ******************************************************************
@ -2385,7 +2469,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetVelocity)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetVelocity(pThis->EmuDirectSound3DBuffer8, x, y, z, dwApply);
return HybridDirectSound3DBuffer_SetVelocity(DSound3DBufferSelectionT(pThis), x, y, z, dwApply);
}
// ******************************************************************
@ -2452,13 +2536,14 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetMode)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetMode(pThis->EmuDirectSound3DBuffer8, dwMode, dwApply);
return HybridDirectSound3DBuffer_SetMode(DSound3DBufferSelectionT(pThis), dwMode, dwApply);
}
// +s
// ******************************************************************
// * patch: IDirectSoundBuffer_SetFormat
// ******************************************************************
// TODO: When SetFormat is called, does Loop and Play region reset, including region buffer?
HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFormat)
(
X_CDirectSoundBuffer* pThis,
@ -2466,12 +2551,20 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetFormat)
{
FUNC_EXPORTS;
enterCriticalSection;
LOG_FUNC_BEGIN
LOG_FUNC_ARG(pThis)
LOG_FUNC_ARG(pwfxFormat)
LOG_FUNC_END;
return HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat, pThis->EmuBufferDesc, pThis->EmuFlags);
HRESULT hRet = HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat, pThis->EmuBufferDesc, pThis->EmuFlags, pThis->EmuPlayFlags, pThis->EmuDirectSound3DBuffer8);
DSoundBufferRegionRelease(pThis);
leaveCriticalSection;
return hRet;
}
// ******************************************************************
@ -2704,7 +2797,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Pause)
pThis->EmuLockBytes2,
pThis->EmuLockFlags);
return HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags);
return HybridDirectSoundBuffer_Pause(DSoundBufferSelectionT(pThis), dwPause, pThis->EmuFlags);
}
//// ******************************************************************
@ -2961,24 +3054,12 @@ extern "C" HRESULT __stdcall XTL::EMUPATCH(IDirectSoundBuffer_PlayEx)
LOG_FUNC_ARG(dwFlags)
LOG_FUNC_END;
DSoundGenericUnlock(pThis->EmuFlags,
pThis->EmuDirectSoundBuffer8,
pThis->EmuBufferDesc,
pThis->EmuLockOffset,
pThis->EmuLockPtr1,
pThis->EmuLockBytes1,
pThis->EmuLockPtr2,
pThis->EmuLockBytes2,
pThis->EmuLockFlags);
pThis->EmuPlayFlags = dwFlags;
//TODO: Need implement support for rtTimeStamp.
if (rtTimeStamp != 0) {
EmuWarning("Not implemented for rtTimeStamp greater than 0 of %08d", rtTimeStamp);
}
HRESULT hRet = HybridDirectSoundBuffer_Play(pThis->EmuDirectSoundBuffer8, pThis->EmuPlayFlags, pThis->EmuFlags);
HRESULT hRet = XTL::EMUPATCH(IDirectSoundBuffer_Play)(pThis, NULL, NULL, dwFlags);
leaveCriticalSection;
@ -3170,7 +3251,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetAllParameters)
LOG_FUNC_ARG(dwApply)
LOG_FUNC_END;
return HybridDirectSound3DBuffer_SetAllParameters(pThis->EmuDirectSound3DBuffer8, pc3DBufferParameters, dwApply);
return HybridDirectSound3DBuffer_SetAllParameters(DSound3DBufferSelectionT(pThis), pc3DBufferParameters, dwApply);
}
// ******************************************************************
@ -3188,7 +3269,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFormat)
LOG_FUNC_ARG(pwfxFormat)
LOG_FUNC_END;
return HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat, pThis->EmuBufferDesc, pThis->EmuFlags);
return HybridDirectSoundBuffer_SetFormat(pThis->EmuDirectSoundBuffer8, pwfxFormat, pThis->EmuBufferDesc, pThis->EmuFlags, pThis->EmuPlayFlags, pThis->EmuDirectSound3DBuffer8);
}
// ******************************************************************
@ -3338,9 +3419,10 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSound_GetEffectData)
LOG_UNIMPLEMENTED_DSOUND();
/* RadWolfie: Should not allocate memory, xbox xbe is just asking for input data, not allocate then input data...
if (!pvData) {
pvData = g_MemoryManager.Allocate(dwDataSize); // TODO : FIXME : Shouldn't this be : *pvData = ... ?!?
}
pvData = malloc(dwDataSize); // TODO : FIXME : Shouldn't this be : *pvData = ... ?!?
}*/
leaveCriticalSection;

View File

@ -67,6 +67,11 @@ void CxbxInitAudio();
#define X_DSSPAUSE_SYNCHPLAYBACK 0x00000002
#define X_DSSPAUSE_PAUSENOACTIVATE 0x00000003
// EmuIDirectSoundBuffer_StopEx flags
#define X_DSBSTOPEX_IMMEDIATE 0x00000000
#define X_DSBSTOPEX_ENVELOPE 0x00000001
#define X_DSBSTOPEX_RELEASEWAVEFORM 0x00000002
// ******************************************************************
// * X_DSBUFFERDESC
@ -280,6 +285,12 @@ struct X_CDirectSound
// TODO: Fill this in?
};
enum X_DSB_TOGGLE {
X_DSB_TOGGLE_DEFAULT = 0,
X_DSB_TOGGLE_PLAY,
X_DSB_TOGGLE_LOOP
};
// ******************************************************************
// * X_CDirectSoundBuffer
// ******************************************************************
@ -305,6 +316,14 @@ struct X_CDirectSoundBuffer
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8;
DWORD EmuLockOffset;
DWORD EmuLockFlags;
// Play/Loop Region Section
X_DSB_TOGGLE EmuBufferToggle;
DWORD EmuRegionLoopStartOffset;
DWORD EmuRegionLoopLength;
DWORD EmuRegionPlayStartOffset;
DWORD EmuRegionPlayLength;
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8Region;
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8Region;
};
#define WAVE_FORMAT_XBOX_ADPCM 0x0069

View File

@ -231,8 +231,9 @@ inline void GeneratePCMFormat(
if (lpwfxFormat->cbSize > 22) {
EmuWarning("WAVEFORMATEXTENSIBLE is detected!");
}
pDSBufferDesc->lpwfxFormat = (WAVEFORMATEX*)g_MemoryManager.Allocate(sizeof(WAVEFORMATEX) + lpwfxFormat->cbSize);
if (pDSBufferDesc->lpwfxFormat == nullptr) {
pDSBufferDesc->lpwfxFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX) + lpwfxFormat->cbSize);
}
memcpy(pDSBufferDesc->lpwfxFormat, lpwfxFormat, sizeof(WAVEFORMATEX));
dwEmuFlags = dwEmuFlags & ~DSB_FLAG_AUDIO_CODECS;
@ -269,7 +270,7 @@ inline void GeneratePCMFormat(
// TODO: A better response to this scenario if possible.
pDSBufferDesc->lpwfxFormat = (WAVEFORMATEX*)g_MemoryManager.Allocate(sizeof(WAVEFORMATEX));
pDSBufferDesc->lpwfxFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX));
//memset(pDSBufferDescSpecial->lpwfxFormat, 0, sizeof(WAVEFORMATEX));
//memset(pDSBufferDescSpecial, 0, sizeof(DSBUFFERDESC));
@ -285,7 +286,7 @@ inline void GeneratePCMFormat(
pDSBufferDesc->dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY;
pDSBufferDesc->dwBufferBytes = 3 * pDSBufferDesc->lpwfxFormat->nAvgBytesPerSec;
// pDSBufferDesc->lpwfxFormat = (WAVEFORMATEX*)g_MemoryManager.Allocate(sizeof(WAVEFORMATEX)/*+pdsbd->lpwfxFormat->cbSize*/);
// pDSBufferDesc->lpwfxFormat = (WAVEFORMATEX*)malloc(sizeof(WAVEFORMATEX)/*+pdsbd->lpwfxFormat->cbSize*/);
//// pDSBufferDesc->lpwfxFormat->cbSize = sizeof( WAVEFORMATEX );
// pDSBufferDesc->lpwfxFormat->nChannels = 1;
@ -364,6 +365,173 @@ inline void DSoundGenericUnlock(
}
#define DSoundBufferSelectionT(pThis) \
((pThis->EmuDirectSoundBuffer8Region != nullptr) ? pThis->EmuDirectSoundBuffer8Region : pThis->EmuDirectSoundBuffer8)
#define DSound3DBufferSelectionT(pThis) \
((pThis->EmuDirectSoundBuffer8Region != nullptr) ? pThis->EmuDirectSound3DBuffer8Region : pThis->EmuDirectSound3DBuffer8)
//Temporary creation since we need IDIRECTSOUNDBUFFER8, not IDIRECTSOUNDBUFFER class.
inline void DSoundBufferCreate(LPDSBUFFERDESC &pDSBufferDesc, LPDIRECTSOUNDBUFFER8 &pDSBuffer)
{
LPDIRECTSOUNDBUFFER pTempBuffer;
HRESULT hRetDS = g_pDSound8->CreateSoundBuffer(pDSBufferDesc, &pTempBuffer, NULL);
if (hRetDS != DS_OK) {
CxbxKrnlCleanup("CreateSoundBuffer Failed!");
pDSBufferDesc = xbnullptr;
} else {
hRetDS = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&(pDSBuffer));
pTempBuffer->Release();
if (hRetDS != DS_OK) {
CxbxKrnlCleanup("Create IDirectSoundBuffer8 Failed!");
}
}
}
inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer) {
HRESULT hRetDS3D = pDSBuffer->QueryInterface(IID_IDirectSound3DBuffer, (LPVOID*)&(pDS3DBuffer));
if (hRetDS3D != DS_OK) {
EmuWarning("CreateSound3DBuffer Failed!");
pDS3DBuffer = nullptr;
}
}
#define DSoundBufferSetDefault(pThis, pdsd, dwEmuFlags, dwEmuPlayFlags) \
pThis->EmuDirectSoundBuffer8 = nullptr; \
pThis->EmuDirectSound3DBuffer8 = nullptr; \
pThis->EmuBuffer = xbnullptr; \
pThis->EmuBufferDesc = pdsd; \
pThis->EmuLockPtr1 = xbnullptr; \
pThis->EmuLockBytes1 = 0; \
pThis->EmuLockPtr2 = xbnullptr; \
pThis->EmuLockBytes2 = 0; \
pThis->EmuFlags = dwEmuFlags; \
pThis->EmuPlayFlags = dwEmuPlayFlags;
inline void DSoundBufferRegionSetDefault(XTL::X_CDirectSoundBuffer *pThis) {
pThis->EmuBufferToggle = XTL::X_DSB_TOGGLE_DEFAULT;
pThis->EmuRegionLoopStartOffset = 0;
pThis->EmuRegionLoopLength = 0;
pThis->EmuRegionPlayStartOffset = 0;
pThis->EmuRegionPlayLength = 0;
pThis->EmuDirectSoundBuffer8Region = nullptr;
pThis->EmuDirectSound3DBuffer8Region = nullptr;
}
inline void DSoundBufferRegionRelease(XTL::X_CDirectSoundBuffer *pThis)
{
if (pThis->EmuDirectSoundBuffer8Region != nullptr) {
pThis->EmuDirectSoundBuffer8Region->Release();
if (pThis->EmuDirectSound3DBuffer8Region != nullptr) {
pThis->EmuDirectSound3DBuffer8Region->Release();
}
}
DSoundBufferRegionSetDefault(pThis);
}
inline void DSoundBufferTransfer(
LPDIRECTSOUNDBUFFER8 &pDSBufferOld,
LPDIRECTSOUNDBUFFER8 &pDSBufferNew,
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferOld,
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew)
{
DWORD dwFrequency;
LONG lVolume, lPan;
DS3DBUFFER ds3dBuffer;
pDSBufferOld->GetVolume(&lVolume);
pDSBufferOld->GetFrequency(&dwFrequency);
pDSBufferOld->GetPan(&lPan);
if (pDS3DBufferOld != nullptr && pDS3DBufferNew != nullptr) {
pDS3DBufferOld->GetAllParameters(&ds3dBuffer);
}
if (pDS3DBufferOld != nullptr && pDS3DBufferNew != nullptr) {
HRESULT hRet3D = pDSBufferOld->QueryInterface(IID_IDirectSound3DBuffer, (LPVOID*)&(pDS3DBufferOld));
if (hRet3D != DS_OK) {
EmuWarning("CreateSound3DBuffer Failed!");
pDS3DBufferOld = nullptr;
} else {
pDS3DBufferNew->SetAllParameters(&ds3dBuffer, DS3D_IMMEDIATE);
}
}
pDSBufferNew->SetPan(lPan);
pDSBufferNew->SetFrequency(dwFrequency);
pDSBufferNew->SetVolume(lVolume);
}
inline void DSoundBufferReplace(
LPDIRECTSOUNDBUFFER8 &pDSBuffer,
LPDSBUFFERDESC pDSBufferDesc,
DWORD PlayFlags,
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer)
{
DWORD refCount, dwPlayCursor, dwWriteCursor, dwStatus;
LPDIRECTSOUNDBUFFER8 pDSBufferNew = nullptr;
LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr;
DSoundBufferCreate(pDSBufferDesc, pDSBufferNew);
if (pDS3DBuffer != nullptr) {
DSound3DBufferCreate(pDSBuffer, pDS3DBufferNew);
}
DSoundBufferTransfer(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew);
if (pDS3DBuffer != nullptr) {
pDS3DBuffer->Release();
}
HRESULT hRet = pDSBuffer->GetCurrentPosition(&dwPlayCursor, &dwWriteCursor);
if (hRet != DS_OK) {
CxbxKrnlCleanup("Unable to retrieve current position for resize reallocation!");
}
hRet = pDSBuffer->GetStatus(&dwStatus);
if (hRet != DS_OK) {
CxbxKrnlCleanup("Unable to retrieve current status for resize reallocation!");
}
pDSBuffer->Stop();
// TODO: Untested if transfer buffer to new audio buffer is necessary.
PVOID pLockPtr1Old, pLockPtr1New;
DWORD dwLockBytes1Old, dwLockBytes1New;
pDSBuffer->Lock(0, 0, &pLockPtr1Old, &dwLockBytes1Old, nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
pDSBufferNew->Lock(0, 0, &pLockPtr1New, &dwLockBytes1New, nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
if (dwLockBytes1Old > dwLockBytes1New) {
memcpy_s(pLockPtr1New, dwLockBytes1New, pLockPtr1Old, dwLockBytes1New);
} else {
memcpy_s(pLockPtr1New, dwLockBytes1Old, pLockPtr1Old, dwLockBytes1Old);
}
pDSBuffer->Unlock(pLockPtr1Old, dwLockBytes1Old, nullptr, 0);
pDSBufferNew->Unlock(pLockPtr1New, dwLockBytes1New, nullptr, 0);
pDSBufferNew->SetCurrentPosition(dwPlayCursor);
if (dwStatus & DSBSTATUS_PLAYING) {
pDSBufferNew->Play(0, 0, PlayFlags);
}
// release old buffer
refCount = pDSBuffer->Release();
if (refCount) {
while (pDSBuffer->Release() > 0) {}
}
pDSBuffer = pDSBufferNew;
pDS3DBuffer = pDS3DBufferNew;
if (refCount) {
while (pDSBuffer->AddRef() < refCount);
}
}
// resize an emulated directsound buffer, if necessary
inline void ResizeIDirectSoundBuffer(
LPDIRECTSOUNDBUFFER8 &pDSBuffer,
@ -378,75 +546,9 @@ inline void ResizeIDirectSoundBuffer(
}
DbgPrintf("EmuResizeIDirectSoundBuffer8 : Resizing! (0x%.08X->0x%.08X)\n", pDSBufferDesc->dwBufferBytes, dwBytes);
DWORD dwPlayCursor, dwWriteCursor, dwStatus, refCount, dwFrequency;
LONG lVolume, lPan;
DS3DBUFFER ds3dBuffer;
pDSBuffer->GetVolume(&lVolume);
pDSBuffer->GetFrequency(&dwFrequency);
pDSBuffer->GetPan(&lPan);
if (pDS3DBuffer != xbnullptr && pDSBufferDesc->dwFlags & DSBCAPS_CTRL3D) {
pDS3DBuffer->GetAllParameters(&ds3dBuffer);
}
HRESULT hRet = pDSBuffer->GetCurrentPosition(&dwPlayCursor, &dwWriteCursor);
if (hRet != DS_OK) {
CxbxKrnlCleanup("Unable to retrieve current position for resize reallocation!");
}
hRet = pDSBuffer->GetStatus(&dwStatus);
if (hRet != DS_OK) {
CxbxKrnlCleanup("Unable to retrieve current status for resize reallocation!");
}
if (pDS3DBuffer != xbnullptr) {
pDS3DBuffer->Release();
}
// release old buffer
refCount = pDSBuffer->Release();
if (refCount) {
while (pDSBuffer->Release() > 0) {}
}
pDSBufferDesc->dwBufferBytes = dwBytes;
//Temporary creation since we need IDIRECTSOUNDBUFFER8, not IDIRECTSOUNDBUFFER class.
LPDIRECTSOUNDBUFFER pTempBuffer;
hRet = g_pDSound8->CreateSoundBuffer(pDSBufferDesc, &pTempBuffer, NULL);
if (hRet != DS_OK) {
CxbxKrnlCleanup("CreateSoundBuffer Failed!");
pDSBufferDesc = xbnullptr;
} else {
hRet = pTempBuffer->QueryInterface(IID_IDirectSoundBuffer8, (LPVOID*)&(pDSBuffer));
pTempBuffer->Release();
}
if (hRet != DS_OK) {
CxbxKrnlCleanup("IDirectSoundBuffer8 resize Failed!");
}
if (refCount) {
while (pDSBuffer->AddRef() < refCount);
}
if (pDS3DBuffer != xbnullptr && pDSBufferDesc->dwFlags & DSBCAPS_CTRL3D) {
HRESULT hRet3D = pDSBuffer->QueryInterface(IID_IDirectSound3DBuffer, (LPVOID*)&(pDS3DBuffer));
if (hRet3D != DS_OK) {
EmuWarning("CreateSound3DBuffer Failed!");
pDS3DBuffer = xbnullptr;
} else {
pDS3DBuffer->SetAllParameters(&ds3dBuffer, DS3D_IMMEDIATE);
}
}
pDSBuffer->SetPan(lPan);
pDSBuffer->SetFrequency(dwFrequency);
pDSBuffer->SetVolume(lVolume);
pDSBuffer->SetCurrentPosition(dwPlayCursor);
if (dwStatus & DSBSTATUS_PLAYING) {
pDSBuffer->Play(0, 0, PlayFlags);
}
DSoundBufferReplace(pDSBuffer, pDSBufferDesc, PlayFlags, pDS3DBuffer);
}
inline void DSoundBufferUpdate(
@ -701,7 +803,7 @@ inline HRESULT HybridDirectSoundBuffer_Process(
return DS_OK;
}*/
/* PlayEx is now calling to Play function instead of this hybrid function.
//Both Play(Ex) only has one function, aka this is not a requirement.
//IDirectSoundBuffer
inline HRESULT HybridDirectSoundBuffer_Play(
@ -735,6 +837,7 @@ inline HRESULT HybridDirectSoundBuffer_Play(
RETURN_RESULT_CHECK(hRet);
}
*/
/*
//IDirectSoundBuffer
inline HRESULT HybridDirectSoundBuffer_PlayEx(
@ -950,10 +1053,12 @@ inline HRESULT HybridDirectSoundBuffer_SetFilter(
//IDirectSoundStream
//IDirectSoundBuffer
inline HRESULT HybridDirectSoundBuffer_SetFormat(
LPDIRECTSOUNDBUFFER8 pDSBuffer,
LPCWAVEFORMATEX pwfxFormat,
LPDSBUFFERDESC pBufferDesc,
DWORD &dwEmuFlags)
LPDIRECTSOUNDBUFFER8 &pDSBuffer,
LPCWAVEFORMATEX pwfxFormat,
LPDSBUFFERDESC pBufferDesc,
DWORD &dwEmuFlags,
DWORD &dwPlayFlags,
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer)
{
enterCriticalSection;
@ -964,7 +1069,7 @@ inline HRESULT HybridDirectSoundBuffer_SetFormat(
if (g_pDSoundPrimaryBuffer == pDSBuffer) {
hRet = pDSBuffer->SetFormat(pBufferDesc->lpwfxFormat);
} else {
//TODO: RadWolfie - Need to create a new buffer in order for this to work base on MSDN document.
DSoundBufferReplace(pDSBuffer, pBufferDesc, dwPlayFlags, pDS3DBuffer);
}
leaveCriticalSection;