From 2ee159fb659331a522b1dd42fefb08eb4be5e757 Mon Sep 17 00:00:00 2001 From: RadWolfie Date: Sun, 1 Apr 2018 16:23:25 -0500 Subject: [PATCH] More fixup for DSound Stream class --- src/CxbxKrnl/EmuDSound.cpp | 57 ++++++++++++-------------------- src/CxbxKrnl/EmuDSoundInline.hpp | 36 ++++++++++++++++++-- 2 files changed, 54 insertions(+), 39 deletions(-) diff --git a/src/CxbxKrnl/EmuDSound.cpp b/src/CxbxKrnl/EmuDSound.cpp index 64ce50d56..4fbe2c365 100755 --- a/src/CxbxKrnl/EmuDSound.cpp +++ b/src/CxbxKrnl/EmuDSound.cpp @@ -508,7 +508,7 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)() // Debug area end if (pThis->Host_isProcessing == false) { - pThis->EmuDirectSoundBuffer8->SetCurrentPosition(0); + pThis->EmuDirectSoundBuffer8->SetCurrentPosition(buffer->rangeStart); pThis->EmuDirectSoundBuffer8->Play(0, 0, pThis->EmuPlayFlags); pThis->Host_isProcessing = true; } @@ -531,22 +531,12 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)() buffer->isPlayed = true; } if (bufPlayed >= (int)buffer->xmp_data.dwMaxSize) { - free(buffer->pBuffer_data); - if (buffer->xmp_data.pdwStatus != xbnullptr) { - (*buffer->xmp_data.pdwStatus) = XMP_STATUS_SUCCESS; - } - if (buffer->xmp_data.pdwCompletedSize != xbnullptr) { - (*buffer->xmp_data.pdwCompletedSize) = DSoundBufferGetXboxBufferSize(pThis->EmuFlags, buffer->xmp_data.dwMaxSize); - } - // If a callback is set, only do the callback instead of event handle. - if (pThis->Xb_lpfnCallback != xbnullptr) { - pThis->Xb_lpfnCallback(pThis->Xb_lpvContext, buffer->xmp_data.pContext, XMP_STATUS_SUCCESS); - } else if (buffer->xmp_data.hCompletionEvent != 0) { - SetEvent(buffer->xmp_data.hCompletionEvent); - } + + DSoundStreamClearPacket(buffer._Ptr, XMP_STATUS_SUCCESS, pThis->Xb_lpfnCallback, pThis->Xb_lpvContext, pThis->EmuFlags); + buffer = pThis->Host_BufferPacketArray.erase(buffer); if (pThis->Host_BufferPacketArray.size() == 0) { - continue; + goto endOfPacket; } if (buffer->isWritten == false) { goto prepareNextBufferPacket; @@ -563,6 +553,13 @@ VOID WINAPI XTL::EMUPATCH(DirectSoundDoWork)() } } } + // Out of packets, let's stop it. + if (pThis->Host_BufferPacketArray.size() == 0) { + + endOfPacket: + pThis->Host_isProcessing = false; + pThis->EmuDirectSoundBuffer8->Stop(); + } } } } @@ -2097,27 +2094,15 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_Flush) DSoundBufferRemoveSynchPlaybackFlag(pThis->EmuFlags); - // Don't process if stream is paused. - if ((pThis->EmuFlags & DSB_FLAG_PAUSE) == 0 && pThis->Host_isProcessing) { - host_voice_packet packetSilence; - packetSilence.xmp_data = { 0 }; - packetSilence.xmp_data.dwMaxSize = pThis->Host_dwTriggerRange; - packetSilence.pBuffer_data = malloc(packetSilence.xmp_data.dwMaxSize); - memset(packetSilence.pBuffer_data, 0, packetSilence.xmp_data.dwMaxSize); - packetSilence.rangeStart = pThis->Host_dwWriteOffsetNext; - packetSilence.isPlayed = false; - packetSilence.isWritten = false; - pThis->Host_BufferPacketArray.push_back(packetSilence); - do { - XTL::EMUPATCH(DirectSoundDoWork)(); - } while (pThis->Host_BufferPacketArray.size() > 1); + pThis->EmuDirectSoundBuffer8->Stop(); + pThis->Host_isProcessing = false; - pThis->EmuDirectSoundBuffer8->Stop(); + for (auto buffer = pThis->Host_BufferPacketArray.begin(); buffer != pThis->Host_BufferPacketArray.end();) { + DSoundStreamClearPacket(buffer._Ptr, XMP_STATUS_FLUSHED, pThis->Xb_lpfnCallback, pThis->Xb_lpvContext, pThis->EmuFlags); + buffer = pThis->Host_BufferPacketArray.erase(buffer); } - pThis->Host_BufferPacketArray.clear(); - leaveCriticalSection; return DS_OK; @@ -2184,7 +2169,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_Pause) LOG_FUNC_ARG(dwPause) LOG_FUNC_END; - return HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags); + return HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags, (pThis->Host_BufferPacketArray.size() > 0)); } // ****************************************************************** @@ -2970,7 +2955,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Pause) pThis->X_lock.dwLockBytes1, pThis->X_lock.dwLockBytes2); - return HybridDirectSoundBuffer_Pause(DSoundBufferSelectionT(pThis), dwPause, pThis->EmuFlags, pThis->EmuPlayFlags); + return HybridDirectSoundBuffer_Pause(DSoundBufferSelectionT(pThis), dwPause, pThis->EmuFlags, pThis->EmuPlayFlags, 1); } // ****************************************************************** @@ -2995,7 +2980,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_PauseEx) // This function wasn't part of the XDK until 4721. // TODO: Implement time stamp feature (a thread maybe?) - HRESULT hRet = HybridDirectSoundBuffer_Pause(DSoundBufferSelectionT(pThis), dwPause, pThis->EmuFlags, pThis->EmuPlayFlags); + HRESULT hRet = HybridDirectSoundBuffer_Pause(DSoundBufferSelectionT(pThis), dwPause, pThis->EmuFlags, pThis->EmuPlayFlags, 1); leaveCriticalSection; @@ -4011,7 +3996,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_PauseEx) // This function wasn't part of the XDK until 4721. (Same as IDirectSoundBuffer_PauseEx?) // TODO: Implement time stamp feature (a thread maybe?) - HRESULT hRet = HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags); + HRESULT hRet = HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags, (pThis->Host_BufferPacketArray.size() > 0)); leaveCriticalSection; diff --git a/src/CxbxKrnl/EmuDSoundInline.hpp b/src/CxbxKrnl/EmuDSoundInline.hpp index 339100600..4211abb2e 100644 --- a/src/CxbxKrnl/EmuDSoundInline.hpp +++ b/src/CxbxKrnl/EmuDSoundInline.hpp @@ -145,6 +145,11 @@ inline void GenerateXboxBufferCache( if (*X_BufferCache != xbnullptr) { LPVOID tempBuffer = *X_BufferCache; *X_BufferCache = malloc(X_BufferSizeRequest); + + // Don't copy over the limit. + if (X_BufferCacheSize > X_BufferSizeRequest) { + X_BufferCacheSize = X_BufferSizeRequest; + } memcpy_s(*X_BufferCache, X_BufferSizeRequest, tempBuffer, X_BufferCacheSize); } else { *X_BufferCache = malloc(X_BufferSizeRequest); @@ -544,6 +549,28 @@ inline void DSoundStreamWriteToBuffer( } } +inline void DSoundStreamClearPacket( + XTL::host_voice_packet* buffer, + DWORD status, + XTL::LPFNXMOCALLBACK Xb_lpfnCallback, + LPVOID Xb_lpvContext, + DWORD EmuFlags) { + + free(buffer->pBuffer_data); + if (buffer->xmp_data.pdwStatus != xbnullptr) { + (*buffer->xmp_data.pdwStatus) = status; + } + if (buffer->xmp_data.pdwCompletedSize != xbnullptr) { + (*buffer->xmp_data.pdwCompletedSize) = DSoundBufferGetXboxBufferSize(EmuFlags, buffer->xmp_data.dwMaxSize); + } + // If a callback is set, only do the callback instead of event handle. + if (Xb_lpfnCallback != xbnullptr) { + Xb_lpfnCallback(Xb_lpvContext, buffer->xmp_data.pContext, status); + } else if (buffer->xmp_data.hCompletionEvent != 0) { + SetEvent(buffer->xmp_data.hCompletionEvent); + } +} + // Generic force remove synch playback control flag. inline void DSoundBufferRemoveSynchPlaybackFlag( DWORD &dwEmuFlags @@ -694,7 +721,8 @@ inline HRESULT HybridDirectSoundBuffer_Pause( LPDIRECTSOUNDBUFFER8 pDSBuffer, DWORD dwPause, DWORD &dwEmuFlags, - DWORD dwEmuPlayFlags) + DWORD dwEmuPlayFlags, + bool triggerPlayPermission) { enterCriticalSection; @@ -703,9 +731,11 @@ inline HRESULT HybridDirectSoundBuffer_Pause( HRESULT hRet = DS_OK, hStatus; switch (dwPause) { case X_DSSPAUSE_RESUME: - pDSBuffer->Play(0, 0, dwEmuPlayFlags); + if (triggerPlayPermission) { + pDSBuffer->Play(0, 0, dwEmuPlayFlags); + } DSoundBufferRemoveSynchPlaybackFlag(dwEmuFlags); - dwEmuFlags ^= DSB_FLAG_PAUSE; + dwEmuFlags &= ~DSB_FLAG_PAUSE; break; case X_DSSPAUSE_PAUSE: hStatus = pDSBuffer->GetStatus(&dwStatus);