Attempted fixup for Ghost Recon titles
I believe there is unauthorized write to xbox pass-down memory since it
show different result from time to time for some reason...
However... Rayman 3 and Rayman Arena titles now shows 2nd intro
properly! 👀 I personally believe this is the best commit for ANY
FMV (background musics are not verified).
This commit is contained in:
parent
2de464fc1b
commit
393703f9d1
|
@ -971,7 +971,6 @@ 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;
|
||||
|
||||
// TODO: Garbage Collection
|
||||
|
@ -980,7 +979,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateBuffer)
|
|||
DSoundBufferSetDefault((*ppBuffer), pDSBufferDesc, 0, 0);
|
||||
(*ppBuffer)->Host_lock = { 0 };
|
||||
|
||||
GeneratePCMFormat(pDSBufferDesc, pdsbd->lpwfxFormat, (*ppBuffer)->EmuFlags, &(*ppBuffer)->X_BufferCache, &(*ppBuffer)->X_BufferCacheSize);
|
||||
GeneratePCMFormat(pDSBufferDesc, pdsbd->lpwfxFormat, (*ppBuffer)->EmuFlags, pdsbd->dwBufferBytes, &(*ppBuffer)->X_BufferCache, (*ppBuffer)->X_BufferCacheSize);
|
||||
DSoundBufferRegionSetDefault(*ppBuffer);
|
||||
|
||||
DbgPrintf("EmuDSound: DirectSoundCreateBuffer, *ppBuffer := 0x%.08X, bytes := 0x%.08X\n", *ppBuffer, pDSBufferDesc->dwBufferBytes);
|
||||
|
@ -1038,23 +1037,23 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
|||
LOG_FUNC_ARG(dwBufferBytes)
|
||||
LOG_FUNC_END;
|
||||
|
||||
|
||||
// Release old buffer if exists, this is needed in order to set lock pointer buffer to nullptr.
|
||||
if (pThis->Host_lock.pLockPtr1 != nullptr) {
|
||||
|
||||
DSoundGenericUnlock(pThis->EmuFlags,
|
||||
pThis->EmuDirectSoundBuffer8,
|
||||
pThis->EmuBufferDesc,
|
||||
pThis->Host_lock,
|
||||
pThis->X_BufferCache,
|
||||
pThis->X_lock.dwLockOffset,
|
||||
pThis->X_lock.dwLockBytes1,
|
||||
pThis->X_lock.dwLockBytes2);
|
||||
}
|
||||
|
||||
//TODO: Current workaround method since dwBufferBytes do set to zero. Otherwise it will produce lock error message.
|
||||
if (dwBufferBytes == 0) {
|
||||
|
||||
|
||||
// Release old buffer if exists, this is needed in order to set lock pointer buffer to nullptr.
|
||||
if (pThis->Host_lock.pLockPtr1 != nullptr) {
|
||||
|
||||
DSoundGenericUnlock(pThis->EmuFlags,
|
||||
pThis->EmuDirectSoundBuffer8,
|
||||
pThis->EmuBufferDesc,
|
||||
pThis->Host_lock,
|
||||
pThis->X_BufferCache,
|
||||
pThis->X_lock.dwLockOffset,
|
||||
pThis->X_lock.dwLockBytes1,
|
||||
pThis->X_lock.dwLockBytes2);
|
||||
}
|
||||
|
||||
leaveCriticalSection;
|
||||
return DS_OK;
|
||||
}
|
||||
|
@ -1066,11 +1065,19 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
|||
ResizeIDirectSoundBuffer(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc,
|
||||
pThis->EmuPlayFlags, dwBufferBytes, pThis->EmuDirectSound3DBuffer8, pThis->EmuFlags, pThis->X_BufferCache, pThis->X_BufferCacheSize);
|
||||
|
||||
XTL::EMUPATCH(IDirectSoundBuffer_Lock)(pThis, 0, dwBufferBytes, &pThis->X_lock.pLockPtr1,
|
||||
&pThis->X_lock.dwLockBytes1, nullptr, NULL, pThis->X_lock.dwLockFlags);
|
||||
DWORD pcmSize = DSoundBufferGetPCMBufferSize(pThis->EmuFlags, dwBufferBytes);
|
||||
|
||||
pThis->EmuDirectSoundBuffer8->Lock(0, pcmSize, &pThis->Host_lock.pLockPtr1, &pThis->Host_lock.dwLockBytes1, &pThis->Host_lock.pLockPtr2, &pThis->Host_lock.dwLockBytes2, DSBLOCK_ENTIREBUFFER);
|
||||
|
||||
memcpy_s(pThis->X_BufferCache, pThis->X_BufferCacheSize, pvBufferData, dwBufferBytes);
|
||||
|
||||
pThis->Host_lock.dwLockOffset = 0;
|
||||
pThis->Host_lock.dwLockFlags = DSBLOCK_ENTIREBUFFER;
|
||||
|
||||
pThis->X_lock.dwLockOffset = 0;
|
||||
pThis->X_lock.dwLockBytes1 = DSoundBufferGetXboxBufferSize(pThis->EmuFlags, pThis->Host_lock.dwLockBytes1);
|
||||
pThis->X_lock.dwLockBytes2 = DSoundBufferGetXboxBufferSize(pThis->EmuFlags, pThis->Host_lock.dwLockBytes2);
|
||||
|
||||
DSoundGenericUnlock(pThis->EmuFlags,
|
||||
pThis->EmuDirectSoundBuffer8,
|
||||
pThis->EmuBufferDesc,
|
||||
|
@ -1080,6 +1087,9 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
|||
pThis->X_lock.dwLockBytes1,
|
||||
pThis->X_lock.dwLockBytes2);
|
||||
|
||||
pThis->X_lock.pLockPtr1 = nullptr;
|
||||
pThis->X_lock.pLockPtr2 = nullptr;
|
||||
|
||||
leaveCriticalSection;
|
||||
|
||||
return S_OK;
|
||||
|
@ -1490,41 +1500,41 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play)
|
|||
|
||||
// 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;
|
||||
DWORD Xb_byteLength;
|
||||
DWORD Xb_startOffset;
|
||||
LPDSBUFFERDESC emuBufferDescRegion = (LPDSBUFFERDESC)malloc(sizeof(DSBUFFERDESC));
|
||||
memcpy_s(emuBufferDescRegion, sizeof(DSBUFFERDESC), pThis->EmuBufferDesc, sizeof(DSBUFFERDESC));
|
||||
|
||||
switch (pThis->EmuBufferToggle) {
|
||||
case X_DSB_TOGGLE_LOOP:
|
||||
startOffset = pThis->EmuRegionPlayStartOffset + pThis->EmuRegionLoopStartOffset;
|
||||
Xb_startOffset = pThis->EmuRegionPlayStartOffset + pThis->EmuRegionLoopStartOffset;
|
||||
|
||||
// Must check for zero length, then apply true length.
|
||||
if (pThis->EmuRegionLoopLength == 0) {
|
||||
if (pThis->EmuRegionPlayLength != 0) {
|
||||
byteLength = pThis->EmuRegionPlayLength;
|
||||
Xb_byteLength = pThis->EmuRegionPlayLength;
|
||||
} else {
|
||||
byteLength = pThis->EmuBufferDesc->dwBufferBytes - startOffset;
|
||||
Xb_byteLength = pThis->X_BufferCacheSize - Xb_startOffset;
|
||||
}
|
||||
} else {
|
||||
byteLength = pThis->EmuRegionLoopLength;
|
||||
Xb_byteLength = pThis->EmuRegionLoopLength;
|
||||
}
|
||||
break;
|
||||
case X_DSB_TOGGLE_PLAY:
|
||||
startOffset = pThis->EmuRegionPlayStartOffset;
|
||||
Xb_startOffset = pThis->EmuRegionPlayStartOffset;
|
||||
|
||||
// Must check for zero length, then apply true length.
|
||||
if (pThis->EmuRegionPlayLength != 0) {
|
||||
byteLength = pThis->EmuRegionPlayLength;
|
||||
Xb_byteLength = pThis->EmuRegionPlayLength;
|
||||
} else {
|
||||
byteLength = pThis->EmuBufferDesc->dwBufferBytes - startOffset;
|
||||
Xb_byteLength = pThis->X_BufferCacheSize - Xb_startOffset;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
free(emuBufferDescRegion);
|
||||
CxbxKrnlCleanup("Unknown TOGGLE region for DirectSoundBuffer class usage.");
|
||||
}
|
||||
emuBufferDescRegion->dwBufferBytes = DSoundBufferGetPCMBufferSize(pThis->EmuFlags, byteLength);
|
||||
emuBufferDescRegion->dwBufferBytes = DSoundBufferGetPCMBufferSize(pThis->EmuFlags, Xb_byteLength);
|
||||
|
||||
DSoundBufferCreate(emuBufferDescRegion, pThis->EmuDirectSoundBuffer8Region);
|
||||
if (pThis->EmuDirectSound3DBuffer8 != nullptr) {
|
||||
|
@ -1539,7 +1549,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_Play)
|
|||
CxbxKrnlCleanup("Unable to lock region buffer!");
|
||||
}
|
||||
if (pThis->Host_lock.pLockPtr1 != nullptr) {
|
||||
DSoundBufferOutputXBtoHost(pThis->EmuFlags, pThis->EmuBufferDesc, (PVOID)((PBYTE)pThis->X_BufferCache + startOffset), byteLength, pThis->Host_lock.pLockPtr1, pThis->Host_lock.dwLockBytes1);
|
||||
DSoundBufferOutputXBtoHost(pThis->EmuFlags, emuBufferDescRegion, (PVOID)((PBYTE)pThis->X_BufferCache + Xb_startOffset), Xb_byteLength, pThis->Host_lock.pLockPtr1, pThis->Host_lock.dwLockBytes1);
|
||||
pThis->EmuDirectSoundBuffer8Region->Unlock(pThis->Host_lock.pLockPtr1, pThis->Host_lock.dwLockBytes1, nullptr, 0);
|
||||
pThis->Host_lock.pLockPtr1 = nullptr;
|
||||
}
|
||||
|
@ -1635,7 +1645,7 @@ HRESULT WINAPI XTL::EMUPATCH(IDirectSoundBuffer_StopEx)
|
|||
|
||||
hRet = pThis->EmuDirectSoundBuffer8Region->Stop();
|
||||
pThis->EmuDirectSoundBuffer8Region->GetCurrentPosition(&dwValue, nullptr);
|
||||
dwValue += pThis->EmuRegionLoopStartOffset + pThis->EmuRegionPlayStartOffset;
|
||||
dwValue += DSoundBufferGetPCMBufferSize(pThis->EmuFlags, pThis->EmuRegionLoopStartOffset + pThis->EmuRegionPlayStartOffset);
|
||||
pThis->EmuDirectSoundBuffer8->SetCurrentPosition(dwValue);
|
||||
|
||||
if (dwStatus & DSBSTATUS_PLAYING) {
|
||||
|
@ -1738,7 +1748,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
|
|||
|
||||
DSoundBufferSetDefault((*ppStream), pDSBufferDesc, 0, DSBPLAY_LOOPING);
|
||||
|
||||
GeneratePCMFormat(pDSBufferDesc, pdssd->lpwfxFormat, (*ppStream)->EmuFlags, xbnullptr, xbnullptr);
|
||||
GeneratePCMFormat(pDSBufferDesc, pdssd->lpwfxFormat, (*ppStream)->EmuFlags, 0, xbnullptr, (*ppStream)->X_BufferCacheSize);
|
||||
|
||||
// Allocate at least 5 second worth of bytes in PCM format.
|
||||
pDSBufferDesc->dwBufferBytes = pDSBufferDesc->lpwfxFormat->nAvgBytesPerSec * 5;
|
||||
|
|
|
@ -50,8 +50,8 @@ CRITICAL_SECTION g_DSoundCriticalSection;
|
|||
#define enterCriticalSection EnterCriticalSection(&g_DSoundCriticalSection)
|
||||
#define leaveCriticalSection LeaveCriticalSection(&g_DSoundCriticalSection)
|
||||
|
||||
#define DSoundBufferGetPCMBufferSize(EmuFlags, size) (EmuFlags & DSB_FLAG_XADPCM) > 0 ? TXboxAdpcmDecoder_guess_output_size(size) : size
|
||||
#define DSoundBufferGetXboxBufferSize(EmuFlags, size) (EmuFlags & DSB_FLAG_XADPCM) > 0 ? ((size / XBOX_ADPCM_DSTSIZE) * XBOX_ADPCM_SRCSIZE) : size
|
||||
#define DSoundBufferGetPCMBufferSize(EmuFlags, size) (EmuFlags & DSB_FLAG_XADPCM) > 0 ? DWORD((size / float(XBOX_ADPCM_SRCSIZE)) * XBOX_ADPCM_DSTSIZE) : size
|
||||
#define DSoundBufferGetXboxBufferSize(EmuFlags, size) (EmuFlags & DSB_FLAG_XADPCM) > 0 ? DWORD((size / float(XBOX_ADPCM_DSTSIZE)) * XBOX_ADPCM_SRCSIZE) : size
|
||||
|
||||
void DSoundBufferOutputXBtoHost(DWORD emuFlags, DSBUFFERDESC* pDSBufferDesc, LPVOID pXBaudioPtr, DWORD dwXBAudioBytes, LPVOID pPCaudioPtr, DWORD dwPCMAudioBytes) {
|
||||
if ((emuFlags & DSB_FLAG_XADPCM) > 0) {
|
||||
|
@ -131,16 +131,38 @@ inline void XADPCM2PCMFormat(LPWAVEFORMATEX lpwfxFormat)
|
|||
#endif
|
||||
}
|
||||
|
||||
inline void GenerateXboxBufferCache(
|
||||
DSBUFFERDESC* pDSBufferDesc,
|
||||
DWORD &dwEmuFlags,
|
||||
DWORD X_BufferSizeRequest,
|
||||
LPVOID* X_BufferCache,
|
||||
DWORD &X_BufferCacheSize) {
|
||||
|
||||
// Generate xbox buffer cache size
|
||||
// If the size is the same, don't realloc
|
||||
if (X_BufferCacheSize != X_BufferSizeRequest) {
|
||||
// Check if buffer cache exist, then copy over old ones.
|
||||
if (*X_BufferCache != xbnullptr) {
|
||||
LPVOID tempBuffer = *X_BufferCache;
|
||||
*X_BufferCache = malloc(X_BufferSizeRequest);
|
||||
memcpy_s(*X_BufferCache, X_BufferSizeRequest, tempBuffer, X_BufferCacheSize);
|
||||
} else {
|
||||
*X_BufferCache = malloc(X_BufferSizeRequest);
|
||||
}
|
||||
X_BufferCacheSize = X_BufferSizeRequest;
|
||||
}
|
||||
}
|
||||
|
||||
inline void GeneratePCMFormat(
|
||||
DSBUFFERDESC* pDSBufferDesc,
|
||||
LPCWAVEFORMATEX lpwfxFormat,
|
||||
DWORD &dwEmuFlags,
|
||||
DWORD X_BufferSizeRequest,
|
||||
LPVOID* X_BufferCache,
|
||||
LPDWORD X_BufferCacheSize)
|
||||
DWORD &X_BufferCacheSize)
|
||||
{
|
||||
bool bIsSpecial = false;
|
||||
DWORD checkAvgBps;
|
||||
DWORD X_BufferSizeRequest = pDSBufferDesc->dwBufferBytes;
|
||||
|
||||
// convert from Xbox to PC DSound
|
||||
{
|
||||
|
@ -184,14 +206,6 @@ inline void GeneratePCMFormat(
|
|||
dwEmuFlags |= DSB_FLAG_PCM_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (pDSBufferDesc->dwBufferBytes < DSBSIZE_MIN) {
|
||||
pDSBufferDesc->dwBufferBytes = DSBSIZE_MIN;
|
||||
} else if (pDSBufferDesc->dwBufferBytes > DSBSIZE_MAX) {
|
||||
pDSBufferDesc->dwBufferBytes = DSBSIZE_MAX;
|
||||
} else {
|
||||
pDSBufferDesc->dwBufferBytes = DSoundBufferGetPCMBufferSize(dwEmuFlags, pDSBufferDesc->dwBufferBytes);
|
||||
}
|
||||
} else {
|
||||
bIsSpecial = true;
|
||||
dwEmuFlags |= DSB_FLAG_RECIEVEDATA;
|
||||
|
@ -258,24 +272,16 @@ inline void GeneratePCMFormat(
|
|||
}
|
||||
}
|
||||
|
||||
if (X_BufferCache == xbnullptr) {
|
||||
return;
|
||||
if (X_BufferSizeRequest < DSBSIZE_MIN) {
|
||||
X_BufferSizeRequest = DSBSIZE_MIN;
|
||||
} else if (X_BufferSizeRequest > DSBSIZE_MAX) {
|
||||
X_BufferSizeRequest = DSBSIZE_MAX;
|
||||
}
|
||||
if (X_BufferCache != nullptr) {
|
||||
GenerateXboxBufferCache(pDSBufferDesc, dwEmuFlags, X_BufferSizeRequest, X_BufferCache, X_BufferCacheSize);
|
||||
}
|
||||
|
||||
// Generate xbox buffer cache size
|
||||
// If the size is the same, don't realloc
|
||||
if (*X_BufferCacheSize == X_BufferSizeRequest) {
|
||||
return;
|
||||
}
|
||||
// Check if buffer cache exist, then copy over old ones.
|
||||
if (*X_BufferCache != xbnullptr) {
|
||||
LPVOID tempBuffer = *X_BufferCache;
|
||||
*X_BufferCache = malloc(X_BufferSizeRequest);
|
||||
memcpy_s(*X_BufferCache, X_BufferSizeRequest, tempBuffer, *X_BufferCacheSize);
|
||||
} else {
|
||||
*X_BufferCache = malloc(X_BufferSizeRequest);
|
||||
}
|
||||
*X_BufferCacheSize = X_BufferSizeRequest;
|
||||
pDSBufferDesc->dwBufferBytes = DSoundBufferGetPCMBufferSize(dwEmuFlags, X_BufferCacheSize);
|
||||
}
|
||||
|
||||
inline void DSoundGenericUnlock(
|
||||
|
@ -503,21 +509,13 @@ inline void ResizeIDirectSoundBuffer(
|
|||
LPVOID &X_BufferCache,
|
||||
DWORD &X_BufferCacheSize)
|
||||
{
|
||||
DWORD pcmSize = DSoundBufferGetPCMBufferSize(EmuFlags, Xbox_dwBytes);
|
||||
if (Xbox_dwBytes == 0 || pcmSize == pDSBufferDesc->dwBufferBytes) {
|
||||
if (Xbox_dwBytes == 0 || X_BufferCacheSize == Xbox_dwBytes) {
|
||||
return;
|
||||
}
|
||||
DbgPrintf("EmuResizeIDirectSoundBuffer8 : Resizing! (0x%.08X->0x%.08X)\n", pDSBufferDesc->dwBufferBytes, pcmSize);
|
||||
|
||||
pDSBufferDesc->dwBufferBytes = pcmSize;
|
||||
GenerateXboxBufferCache(pDSBufferDesc, EmuFlags, Xbox_dwBytes, &X_BufferCache, X_BufferCacheSize);
|
||||
|
||||
LPVOID X_tempBuffer = X_BufferCache;
|
||||
X_BufferCache = malloc(Xbox_dwBytes);
|
||||
if (X_tempBuffer != xbnullptr) {
|
||||
memcpy_s(X_BufferCache, Xbox_dwBytes, X_tempBuffer, X_BufferCacheSize);
|
||||
free(X_tempBuffer);
|
||||
}
|
||||
X_BufferCacheSize = Xbox_dwBytes;
|
||||
pDSBufferDesc->dwBufferBytes = DSoundBufferGetPCMBufferSize(EmuFlags, X_BufferCacheSize);
|
||||
|
||||
DSoundBufferReplace(pDSBuffer, pDSBufferDesc, PlayFlags, pDS3DBuffer);
|
||||
}
|
||||
|
@ -1023,10 +1021,10 @@ inline HRESULT HybridDirectSoundBuffer_SetFormat(
|
|||
enterCriticalSection;
|
||||
|
||||
if (X_BufferAllocate) {
|
||||
GeneratePCMFormat(pBufferDesc, pwfxFormat, dwEmuFlags, &X_BufferCache, &X_BufferCacheSize);
|
||||
GeneratePCMFormat(pBufferDesc, pwfxFormat, dwEmuFlags, X_BufferCacheSize, xbnullptr, X_BufferCacheSize);
|
||||
// Don't allocate for DS Stream class, it is using straight from the source.
|
||||
} else {
|
||||
GeneratePCMFormat(pBufferDesc, pwfxFormat, dwEmuFlags, xbnullptr, xbnullptr);
|
||||
GeneratePCMFormat(pBufferDesc, pwfxFormat, dwEmuFlags, 0, xbnullptr, X_BufferCacheSize);
|
||||
}
|
||||
HRESULT hRet = DS_OK;
|
||||
if (g_pDSoundPrimaryBuffer == pDSBuffer) {
|
||||
|
|
Loading…
Reference in New Issue