More fixup for DSound Stream class

This commit is contained in:
RadWolfie 2018-04-01 16:23:25 -05:00
parent 393703f9d1
commit 2ee159fb65
2 changed files with 54 additions and 39 deletions

View File

@ -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;

View File

@ -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);