dsound: fix stream class to match hardware with latest sampling log
This commit is contained in:
parent
471f3894cc
commit
ee9612e263
|
@ -75,13 +75,6 @@ void DSStream_Packet_Clear(
|
|||
|
||||
free(buffer->pBuffer_data);
|
||||
|
||||
// Peform release only, don't trigger any events below.
|
||||
if (status == XMP_STATUS_RELEASE_CXBXR) {
|
||||
DSoundSGEMemDealloc(buffer->xmp_data.dwMaxSize);
|
||||
buffer = pThis->Host_BufferPacketArray.erase(buffer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer->xmp_data.pdwStatus != xbox::zeroptr) {
|
||||
(*buffer->xmp_data.pdwStatus) = status;
|
||||
}
|
||||
|
@ -218,6 +211,16 @@ bool DSStream_Packet_Process(
|
|||
return 0;
|
||||
}
|
||||
|
||||
// Do not allow to process when the voice is not activated.
|
||||
if ((pThis->EmuFlags & DSE_FLAG_PAUSENOACTIVATE) != 0 &&
|
||||
(pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED)) {
|
||||
pThis->EmuFlags |= DSE_FLAG_IS_ACTIVATED;
|
||||
}
|
||||
|
||||
// If title want to pause, then don't process the packets.
|
||||
// If media object is being used as playback synch, then don't process the packets.
|
||||
if ((pThis->EmuFlags & DSE_FLAG_PAUSE) > 0 ||
|
||||
|
@ -228,16 +231,6 @@ bool DSStream_Packet_Process(
|
|||
return 0;
|
||||
}
|
||||
|
||||
if ((pThis->Xb_Status & X_DSSSTATUS_PAUSED) > 0) {
|
||||
pThis->Xb_Status &= ~X_DSSSTATUS_PAUSED;
|
||||
}
|
||||
|
||||
if (pThis->Host_isProcessing == false) {
|
||||
if (!(pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED)) {
|
||||
pThis->EmuFlags |= DSE_FLAG_IS_ACTIVATED;
|
||||
}
|
||||
}
|
||||
|
||||
DWORD dwAudioBytes;
|
||||
HRESULT hRet = pThis->EmuDirectSoundBuffer8->GetStatus(&dwAudioBytes);
|
||||
if (hRet == DS_OK) {
|
||||
|
@ -372,7 +365,7 @@ bool DSStream_Packet_Flush(
|
|||
}
|
||||
// Clear flags and set status to zero.
|
||||
DSStream_Packet_FlushEx_Reset(pThis);
|
||||
pThis->EmuFlags &= ~DSE_FLAG_PAUSE;
|
||||
pThis->EmuFlags &= ~(DSE_FLAG_PAUSE | DSE_FLAG_IS_ACTIVATED);
|
||||
pThis->Xb_Status = 0;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -133,9 +133,10 @@ struct SharedDSBuffer : DSBUFFER_S {
|
|||
#define DSE_FLAG_PCM_UNKNOWN (1 << 2)
|
||||
#define DSE_FLAG_SYNCHPLAYBACK_CONTROL (1 << 10)
|
||||
#define DSE_FLAG_PAUSE (1 << 11)
|
||||
#define DSE_FLAG_FLUSH_ASYNC (1 << 12)
|
||||
#define DSE_FLAG_ENVELOPE (1 << 13)
|
||||
#define DSE_FLAG_ENVELOPE2 (1 << 14) // NOTE: This flag is a requirement for GetStatus to return X_DSSSTATUS_ENVELOPECOMPLETE value.
|
||||
#define DSE_FLAG_PAUSENOACTIVATE (1 << 12)
|
||||
#define DSE_FLAG_FLUSH_ASYNC (1 << 13)
|
||||
#define DSE_FLAG_ENVELOPE (1 << 14)
|
||||
#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_IS_ACTIVATED (1 << 21) // Only used for DirectSoundStream class, to acknowledge pause's no activate flag.
|
||||
#define DSE_FLAG_DEBUG_MUTE (1 << 30) // Cxbx-R debugging usage only
|
||||
|
|
|
@ -849,14 +849,16 @@ static inline HRESULT HybridDirectSoundBuffer_Pause(
|
|||
pDSBuffer->Play(0, 0, dwEmuPlayFlags);
|
||||
}
|
||||
DSoundBufferSynchPlaybackFlagRemove(dwEmuFlags);
|
||||
dwEmuFlags &= ~DSE_FLAG_PAUSE;
|
||||
dwEmuFlags &= ~(DSE_FLAG_PAUSE | DSE_FLAG_PAUSENOACTIVATE);
|
||||
Xb_rtTimeStamp = 0;
|
||||
break;
|
||||
case X_DSSPAUSE_PAUSE:
|
||||
pDSBuffer->Stop();
|
||||
DSoundBufferSynchPlaybackFlagRemove(dwEmuFlags);
|
||||
dwEmuFlags |= DSE_FLAG_PAUSE;
|
||||
Xb_rtTimeStamp = rtTimeStamp;
|
||||
if ((dwEmuFlags & DSE_FLAG_PAUSENOACTIVATE) == 0) {
|
||||
dwEmuFlags |= DSE_FLAG_PAUSE;
|
||||
Xb_rtTimeStamp = rtTimeStamp;
|
||||
}
|
||||
break;
|
||||
case X_DSSPAUSE_SYNCHPLAYBACK:
|
||||
//TODO: Test case Rayman 3 - Hoodlum Havoc, Battlestar Galactica, Miami Vice, Star Wars: KotOR, and... ?
|
||||
|
@ -867,8 +869,13 @@ static inline HRESULT HybridDirectSoundBuffer_Pause(
|
|||
pDSBuffer->Stop();
|
||||
}
|
||||
break;
|
||||
// TODO: NOTE: If stream is playing, it perform same behavior as pause flag. If it is not played, it act as a queue until trigger to play it.
|
||||
// NOTE: If stream is paused with packets, it will trigger to play. If it is not played, it act as a queue until trigger to play it.
|
||||
case X_DSSPAUSE_PAUSENOACTIVATE:
|
||||
dwEmuFlags &= ~DSE_FLAG_PAUSE;
|
||||
if ((dwEmuFlags & DSE_FLAG_IS_ACTIVATED) == 0) {
|
||||
dwEmuFlags |= DSE_FLAG_PAUSENOACTIVATE;
|
||||
Xb_rtTimeStamp = rtTimeStamp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ void DirectSoundDoWork_Stream(xbox::LARGE_INTEGER& time)
|
|||
// TODO: Do we need this in async thread loop?
|
||||
if (pThis->Xb_rtPauseEx != 0LL && pThis->Xb_rtPauseEx <= time.QuadPart) {
|
||||
pThis->Xb_rtPauseEx = 0LL;
|
||||
pThis->EmuFlags &= ~DSE_FLAG_PAUSE;
|
||||
pThis->EmuFlags &= ~(DSE_FLAG_PAUSE | DSE_FLAG_PAUSENOACTIVATE);
|
||||
// Don't call play here, let DSStream_Packet_Process deal with it.
|
||||
}
|
||||
// If has flush async requested then verify time has expired to perform flush process.
|
||||
|
@ -191,7 +191,7 @@ xbox::ulong_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Release)
|
|||
}
|
||||
|
||||
for (auto buffer = pThis->Host_BufferPacketArray.begin(); buffer != pThis->Host_BufferPacketArray.end();) {
|
||||
DSStream_Packet_Clear(buffer, XMP_STATUS_RELEASE_CXBXR, nullptr, nullptr, pThis);
|
||||
DSStream_Packet_Clear(buffer, XMP_STATUS_FLUSHED, pThis->Xb_lpfnCallback, pThis->Xb_lpvContext, pThis);
|
||||
}
|
||||
|
||||
if (pThis->EmuBufferDesc.lpwfxFormat != nullptr) {
|
||||
|
@ -549,14 +549,16 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_GetStatus__r2)
|
|||
|
||||
// Convert host to xbox status flag.
|
||||
if (hRet == DS_OK) {
|
||||
if (pThis->Host_isProcessing && !(dwStatusXbox & X_DSSSTATUS_PAUSED)) {
|
||||
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) {
|
||||
dwStatusXbox |= X_DSSSTATUS_READY;
|
||||
}
|
||||
|
||||
if (!pThis->Host_BufferPacketArray.empty() && (pThis->EmuFlags & DSE_FLAG_PAUSE) != 0) {
|
||||
dwStatusXbox |= X_DSSSTATUS_PAUSED;
|
||||
}
|
||||
} else {
|
||||
dwStatusXbox = 0;
|
||||
hRet = DSERR_GENERIC;
|
||||
|
@ -601,13 +603,32 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_GetVoiceProperties)
|
|||
return hRet;
|
||||
}
|
||||
|
||||
|
||||
xbox::hresult_xt CxbxrImpl_CDirectSoundStream_PauseEx(
|
||||
xbox::X_CDirectSoundStream* pThis,
|
||||
xbox::REFERENCE_TIME rtTimestamp,
|
||||
xbox::dword_xt dwPause)
|
||||
{
|
||||
xbox::hresult_xt hRet = HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags,
|
||||
pThis->Host_isProcessing, rtTimestamp, pThis->Xb_rtPauseEx);
|
||||
|
||||
if ((pThis->EmuFlags & DSE_FLAG_PAUSE) != 0) {
|
||||
pThis->Host_isProcessing = false;
|
||||
}
|
||||
else if (!pThis->Host_isProcessing) {
|
||||
DSStream_Packet_Process(pThis);
|
||||
}
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: CDirectSoundStream_Pause
|
||||
// ******************************************************************
|
||||
xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Pause)
|
||||
(
|
||||
X_CDirectSoundStream* pThis,
|
||||
dword_xt dwPause)
|
||||
dword_xt dwPause)
|
||||
{
|
||||
DSoundMutexGuardLock;
|
||||
|
||||
|
@ -621,26 +642,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Pause)
|
|||
return xbox::status_success;
|
||||
}
|
||||
|
||||
HRESULT hRet = HybridDirectSoundBuffer_Pause(pThis->EmuDirectSoundBuffer8, dwPause, pThis->EmuFlags, pThis->EmuPlayFlags,
|
||||
pThis->Host_isProcessing, 0LL, pThis->Xb_rtPauseEx);
|
||||
|
||||
if (dwPause == X_DSSPAUSE_PAUSENOACTIVATE) {
|
||||
if (pThis->Host_BufferPacketArray.size() == 0 && !(pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED)) {
|
||||
pThis->EmuFlags |= DSE_FLAG_PAUSE;
|
||||
}
|
||||
}
|
||||
|
||||
if ((pThis->EmuFlags & DSE_FLAG_PAUSE) > 0) {
|
||||
pThis->Host_isProcessing = false;
|
||||
if ((pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED) > 0) {
|
||||
if (pThis->Host_BufferPacketArray.size() != 0) {
|
||||
pThis->Xb_Status |= X_DSSSTATUS_PAUSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!pThis->Host_isProcessing) {
|
||||
DSStream_Packet_Process(pThis);
|
||||
}
|
||||
HRESULT hRet = CxbxrImpl_CDirectSoundStream_PauseEx(pThis, 0LL, dwPause);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -652,7 +654,7 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_PauseEx)
|
|||
(
|
||||
X_CDirectSoundStream *pThis,
|
||||
REFERENCE_TIME rtTimestamp,
|
||||
dword_xt dwPause)
|
||||
dword_xt dwPause)
|
||||
{
|
||||
DSoundMutexGuardLock;
|
||||
|
||||
|
@ -663,10 +665,8 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_PauseEx)
|
|||
LOG_FUNC_END;
|
||||
|
||||
// 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,
|
||||
pThis->Host_isProcessing, rtTimestamp, pThis->Xb_rtPauseEx);
|
||||
HRESULT hRet = CxbxrImpl_CDirectSoundStream_PauseEx(pThis, rtTimestamp, dwPause);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -735,9 +735,6 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSoundStream_Process)
|
|||
if ((pThis->Xb_Status & X_DSSSTATUS_STARVED) > 0) {
|
||||
pThis->Xb_Status &= ~X_DSSSTATUS_STARVED;
|
||||
}
|
||||
if ((pThis->EmuFlags & DSE_FLAG_IS_ACTIVATED) > 0 && (pThis->EmuFlags & DSE_FLAG_PAUSE) > 0) {
|
||||
pThis->Xb_Status |= X_DSSSTATUS_PAUSED;
|
||||
}
|
||||
DSStream_Packet_Process(pThis);
|
||||
// Once full it needs to change status to flushed when cannot hold any more packets.
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue