dsound: fix async flush
This commit is contained in:
parent
f872bb5f8a
commit
07c3f3b0fa
|
@ -217,6 +217,10 @@ bool DSStream_Packet_Process(
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pThis->EmuFlags & DSE_FLAG_IS_FLUSHING) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED)) {
|
if (!(pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED)) {
|
||||||
pThis->EmuFlags |= DSE_FLAG_IS_ACTIVATED;
|
pThis->EmuFlags |= DSE_FLAG_IS_ACTIVATED;
|
||||||
}
|
}
|
||||||
|
@ -347,7 +351,9 @@ bool DSStream_Packet_Flush(
|
||||||
xbox::X_CDirectSoundStream* pThis
|
xbox::X_CDirectSoundStream* pThis
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if ((pThis->EmuFlags & DSE_FLAG_IS_FLUSHING) == 0) {
|
||||||
|
pThis->EmuFlags |= DSE_FLAG_IS_FLUSHING;
|
||||||
|
}
|
||||||
// If host's audio is still playing then return busy-state until buffer has stop playing.
|
// If host's audio is still playing then return busy-state until buffer has stop playing.
|
||||||
DWORD dwStatus;
|
DWORD dwStatus;
|
||||||
pThis->EmuDirectSoundBuffer8->GetStatus(&dwStatus);
|
pThis->EmuDirectSoundBuffer8->GetStatus(&dwStatus);
|
||||||
|
@ -373,5 +379,6 @@ bool DSStream_Packet_Flush(
|
||||||
if ((pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED) != 0) {
|
if ((pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED) != 0) {
|
||||||
pThis->EmuFlags &= ~(DSE_FLAG_PAUSE | DSE_FLAG_IS_ACTIVATED);
|
pThis->EmuFlags &= ~(DSE_FLAG_PAUSE | DSE_FLAG_IS_ACTIVATED);
|
||||||
}
|
}
|
||||||
|
pThis->EmuFlags &= ~DSE_FLAG_IS_FLUSHING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,6 +139,7 @@ struct SharedDSBuffer : DSBUFFER_S {
|
||||||
#define DSE_FLAG_ENVELOPE2 (1 << 15) // NOTE: This flag is a requirement for GetStatus to return X_DSSSTATUS_ENVELOPECOMPLETE value.
|
#define DSE_FLAG_ENVELOPE2 (1 << 15) // NOTE: This flag is a requirement for GetStatus to return X_DSSSTATUS_ENVELOPECOMPLETE value.
|
||||||
#define DSE_FLAG_RECIEVEDATA (1 << 20)
|
#define DSE_FLAG_RECIEVEDATA (1 << 20)
|
||||||
#define DSE_FLAG_IS_ACTIVATED (1 << 21) // Only used for DirectSoundStream class, to acknowledge pause's no activate flag.
|
#define DSE_FLAG_IS_ACTIVATED (1 << 21) // Only used for DirectSoundStream class, to acknowledge pause's no activate flag.
|
||||||
|
#define DSE_FLAG_IS_FLUSHING (1 << 22) // Only used for DirectSoundStream class, to acknowledge pause's no activate flag.
|
||||||
#define DSE_FLAG_DEBUG_MUTE (1 << 30) // Cxbx-R debugging usage only
|
#define DSE_FLAG_DEBUG_MUTE (1 << 30) // Cxbx-R debugging usage only
|
||||||
#define DSE_FLAG_BUFFER_EXTERNAL (1 << 31)
|
#define DSE_FLAG_BUFFER_EXTERNAL (1 << 31)
|
||||||
#define DSE_FLAG_AUDIO_CODECS (DSE_FLAG_PCM | DSE_FLAG_XADPCM | DSE_FLAG_PCM_UNKNOWN)
|
#define DSE_FLAG_AUDIO_CODECS (DSE_FLAG_PCM | DSE_FLAG_XADPCM | DSE_FLAG_PCM_UNKNOWN)
|
||||||
|
|
|
@ -380,6 +380,18 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Discontinuity)
|
||||||
return DS_OK;
|
return DS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xbox::hresult_xt CxbxrImpl_CDirectSoundStream_Flush
|
||||||
|
(
|
||||||
|
xbox::X_CDirectSoundStream* pThis)
|
||||||
|
{
|
||||||
|
|
||||||
|
DSoundBufferSynchPlaybackFlagRemove(pThis->EmuFlags);
|
||||||
|
|
||||||
|
while (DSStream_Packet_Flush(pThis));
|
||||||
|
|
||||||
|
return DS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
// * patch: CDirectSoundStream_Flush
|
// * patch: CDirectSoundStream_Flush
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -391,11 +403,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Flush)
|
||||||
|
|
||||||
LOG_FUNC_ONE_ARG(pThis);
|
LOG_FUNC_ONE_ARG(pThis);
|
||||||
|
|
||||||
DSoundBufferSynchPlaybackFlagRemove(pThis->EmuFlags);
|
return CxbxrImpl_CDirectSoundStream_Flush(pThis);
|
||||||
|
|
||||||
while (DSStream_Packet_Flush(pThis));
|
|
||||||
|
|
||||||
return DS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ******************************************************************
|
// ******************************************************************
|
||||||
|
@ -422,22 +430,20 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_FlushEx)
|
||||||
// Cannot use rtTimeStamp here, it must be flush.
|
// Cannot use rtTimeStamp here, it must be flush.
|
||||||
if (dwFlags == X_DSSFLUSHEX_IMMEDIATE) {
|
if (dwFlags == X_DSSFLUSHEX_IMMEDIATE) {
|
||||||
|
|
||||||
hRet = xbox::EMUPATCH(CDirectSoundStream_Flush)(pThis);
|
hRet = CxbxrImpl_CDirectSoundStream_Flush(pThis);
|
||||||
|
|
||||||
}
|
}
|
||||||
// Remaining flags require X_DSSFLUSHEX_ASYNC to be include.
|
// Remaining flags require X_DSSFLUSHEX_ASYNC to be include.
|
||||||
else if ((dwFlags & X_DSSFLUSHEX_ASYNC) > 0) {
|
else if ((dwFlags & X_DSSFLUSHEX_ASYNC) > 0 && !pThis->Host_BufferPacketArray.empty()) {
|
||||||
// If rtTimeStamp is zero'd, then call flush once and allow process flush in worker thread.
|
// If rtTimeStamp is zero'd, then call flush once and allow process flush in worker thread.
|
||||||
if (rtTimeStamp == 0LL) {
|
if (rtTimeStamp == 0LL) {
|
||||||
bool isBusy = DSStream_Packet_Flush(pThis);
|
|
||||||
if (!isBusy) {
|
|
||||||
// testcase: Obscure will crash after new game's video if not call DSStream_Packet_Flush in same thread.
|
|
||||||
// If flush is not busy, then we don't need worker thread to continue flushing.
|
|
||||||
return hRet;
|
|
||||||
}
|
|
||||||
xbox::LARGE_INTEGER getTime;
|
xbox::LARGE_INTEGER getTime;
|
||||||
xbox::KeQuerySystemTime(&getTime);
|
xbox::KeQuerySystemTime(&getTime);
|
||||||
pThis->Xb_rtFlushEx = getTime.QuadPart;
|
pThis->Xb_rtFlushEx = getTime.QuadPart;
|
||||||
|
pThis->EmuFlags |= DSE_FLAG_IS_FLUSHING;
|
||||||
|
// HACK: Need to find a way to remove Flush call without break Obscure.
|
||||||
|
// Otherwise, it will behave like on hardware.
|
||||||
|
DSStream_Packet_Flush(pThis);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pThis->Xb_rtFlushEx = rtTimeStamp;
|
pThis->Xb_rtFlushEx = rtTimeStamp;
|
||||||
|
@ -549,16 +555,17 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_GetStatus__r2)
|
||||||
|
|
||||||
// Convert host to xbox status flag.
|
// Convert host to xbox status flag.
|
||||||
if (hRet == DS_OK) {
|
if (hRet == DS_OK) {
|
||||||
if (!pThis->Host_BufferPacketArray.empty() && (pThis->EmuFlags & (DSE_FLAG_PAUSE | DSE_FLAG_PAUSENOACTIVATE)) == 0) {
|
|
||||||
dwStatusXbox |= X_DSSSTATUS_PLAYING;
|
|
||||||
|
|
||||||
}
|
|
||||||
if (pThis->Host_BufferPacketArray.size() != pThis->X_MaxAttachedPackets) {
|
if (pThis->Host_BufferPacketArray.size() != pThis->X_MaxAttachedPackets) {
|
||||||
dwStatusXbox |= X_DSSSTATUS_READY;
|
dwStatusXbox |= X_DSSSTATUS_READY;
|
||||||
}
|
}
|
||||||
if (!pThis->Host_BufferPacketArray.empty() && (pThis->EmuFlags & DSE_FLAG_PAUSE) != 0) {
|
if (!pThis->Host_BufferPacketArray.empty()) {
|
||||||
|
if ((pThis->EmuFlags & DSE_FLAG_PAUSE) != 0) {
|
||||||
dwStatusXbox |= X_DSSSTATUS_PAUSED;
|
dwStatusXbox |= X_DSSSTATUS_PAUSED;
|
||||||
}
|
}
|
||||||
|
else if ((pThis->EmuFlags & (DSE_FLAG_PAUSE | DSE_FLAG_PAUSENOACTIVATE | DSE_FLAG_IS_FLUSHING)) == 0) {
|
||||||
|
dwStatusXbox |= X_DSSSTATUS_PLAYING;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
dwStatusXbox = 0;
|
dwStatusXbox = 0;
|
||||||
hRet = DSERR_GENERIC;
|
hRet = DSERR_GENERIC;
|
||||||
|
@ -735,6 +742,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Process)
|
||||||
if ((pThis->Xb_Status & X_DSSSTATUS_STARVED) > 0) {
|
if ((pThis->Xb_Status & X_DSSSTATUS_STARVED) > 0) {
|
||||||
pThis->Xb_Status &= ~X_DSSSTATUS_STARVED;
|
pThis->Xb_Status &= ~X_DSSSTATUS_STARVED;
|
||||||
}
|
}
|
||||||
|
pThis->EmuFlags &= ~DSE_FLAG_IS_FLUSHING;
|
||||||
DSStream_Packet_Process(pThis);
|
DSStream_Packet_Process(pThis);
|
||||||
// Once full it needs to change status to flushed when cannot hold any more packets.
|
// Once full it needs to change status to flushed when cannot hold any more packets.
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue