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:
parent
7fc65b57ce
commit
c9ebe3ed18
|
@ -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!");
|
||||
}
|
||||
DSoundBufferCreate(pDSBufferDesc, (*ppBuffer)->EmuDirectSoundBuffer8);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
DSound3DBufferCreate((*ppBuffer)->EmuDirectSoundBuffer8, (*ppBuffer)->EmuDirectSound3DBuffer8);
|
||||
}
|
||||
|
||||
// cache this sound buffer
|
||||
|
@ -927,11 +902,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
|||
return DS_OK;
|
||||
}
|
||||
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,11 +1397,17 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Stop)
|
|||
|
||||
HRESULT hRet = D3D_OK;
|
||||
|
||||
if (pThis != nullptr && pThis->EmuDirectSoundBuffer8 != nullptr) {
|
||||
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,32 +1574,14 @@ 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!");
|
||||
DSoundBufferCreate(pDSBufferDesc, (*ppStream)->EmuDirectSoundBuffer8);
|
||||
if (pDSBufferDesc->dwFlags & DSBCAPS_CTRL3D) {
|
||||
DSound3DBufferCreate((*ppStream)->EmuDirectSoundBuffer8, (*ppStream)->EmuDirectSound3DBuffer8);
|
||||
}
|
||||
|
||||
(*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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// __asm int 3
|
||||
|
||||
// cache this sound stream
|
||||
{
|
||||
int v = 0;
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
LPDIRECTSOUNDBUFFER8 &pDSBuffer,
|
||||
LPCWAVEFORMATEX pwfxFormat,
|
||||
LPDSBUFFERDESC pBufferDesc,
|
||||
DWORD &dwEmuFlags)
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue