implement hybrid buffer for partial internal exposure
This commit is contained in:
parent
dab7a608c2
commit
d7d1d781d8
|
@ -154,6 +154,7 @@ file (GLOB CXBXR_HEADER_EMU
|
|||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.hpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.hpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundTypes.h"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.hpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/Intercept.hpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/Patches.hpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.h"
|
||||
|
@ -296,6 +297,8 @@ file (GLOB CXBXR_SOURCE_EMU
|
|||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/DSStream_PacketManager.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/DirectSound/XFileMediaObject.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/XbDSoundLogging.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalDSVoice.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/DSOUND/common/XbInternalStruct.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/Intercept.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/Patches.cpp"
|
||||
"${CXBXR_ROOT_DIR}/src/core/hle/XACTENG/XactEng.cpp"
|
||||
|
|
|
@ -887,14 +887,15 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSound_SynchPlayback)
|
|||
|
||||
vector_ds_buffer::iterator ppDSBuffer = g_pDSoundBufferCache.begin();
|
||||
for (; ppDSBuffer != g_pDSoundBufferCache.end(); ppDSBuffer++) {
|
||||
if ((*ppDSBuffer)->X_BufferCache == nullptr) {
|
||||
EmuDirectSoundBuffer* pDSBuffer = (*ppDSBuffer)->emuDSBuffer;
|
||||
if (pDSBuffer->X_BufferCache == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((*ppDSBuffer)->EmuFlags & DSE_FLAG_SYNCHPLAYBACK_CONTROL) > 0) {
|
||||
DSoundBufferSynchPlaybackFlagRemove((*ppDSBuffer)->EmuFlags);
|
||||
EmuLog(LOG_LEVEL::DEBUG, "SynchPlayback - pDSBuffer: %08X; EmuPlayFlags: %08X", *ppDSBuffer, (*ppDSBuffer)->EmuPlayFlags);
|
||||
(*ppDSBuffer)->EmuDirectSoundBuffer8->Play(0, 0, (*ppDSBuffer)->EmuPlayFlags);
|
||||
if ((pDSBuffer->EmuFlags & DSE_FLAG_SYNCHPLAYBACK_CONTROL) > 0) {
|
||||
DSoundBufferSynchPlaybackFlagRemove(pDSBuffer->EmuFlags);
|
||||
EmuLog(LOG_LEVEL::DEBUG, "SynchPlayback - pDSBuffer: %08X; EmuPlayFlags: %08X", *ppDSBuffer, pDSBuffer->EmuPlayFlags);
|
||||
pDSBuffer->EmuDirectSoundBuffer8->Play(0, 0, pDSBuffer->EmuPlayFlags);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include "core\kernel\init\CxbxKrnl.h"
|
||||
#include "core\hle\DSOUND\XbDSoundTypes.h"
|
||||
#include "core\hle\DSOUND\common\XbInternalStruct.hpp"
|
||||
|
||||
typedef struct IDirectSound3DListener8* LPDIRECTSOUND3DLISTENER8;
|
||||
typedef struct IDirectSound3DBuffer8* LPDIRECTSOUND3DBUFFER8;
|
||||
|
@ -73,25 +74,21 @@ typedef struct _DSoundBuffer_Lock {
|
|||
// ******************************************************************
|
||||
// * X_CDirectSoundBuffer
|
||||
// ******************************************************************
|
||||
struct X_CDirectSoundBuffer
|
||||
struct EmuDirectSoundBuffer
|
||||
{
|
||||
BYTE UnknownA[0x20]; // Offset: 0x00
|
||||
|
||||
union // Offset: 0x20
|
||||
union
|
||||
{
|
||||
PVOID pMpcxBuffer;
|
||||
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8;
|
||||
};
|
||||
|
||||
BYTE UnknownB[0x0C]; // Offset: 0x24
|
||||
LPVOID X_BufferCache; // Offset: 0x28
|
||||
DSBUFFERDESC EmuBufferDesc; // Offset: 0x2C
|
||||
/*LPVOID EmuLockPtr1; // Offset: 0x30
|
||||
DWORD EmuLockBytes1; // Offset: 0x34
|
||||
LPVOID EmuLockPtr2; // Offset: 0x38
|
||||
DWORD EmuLockBytes2; // Offset: 0x3C*/
|
||||
DWORD EmuPlayFlags; // Offset: 0x40
|
||||
DWORD EmuFlags; // Offset: 0x44
|
||||
LPVOID X_BufferCache;
|
||||
DSBUFFERDESC EmuBufferDesc;
|
||||
/*LPVOID EmuLockPtr1;
|
||||
DWORD EmuLockBytes1;
|
||||
LPVOID EmuLockPtr2;
|
||||
DWORD EmuLockBytes2;*/
|
||||
DWORD EmuPlayFlags;
|
||||
DWORD EmuFlags;
|
||||
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8;
|
||||
//DWORD EmuLockOffset;
|
||||
//DWORD EmuLockFlags;
|
||||
|
@ -111,9 +108,19 @@ struct X_CDirectSoundBuffer
|
|||
DWORD Xb_dwHeadroom;
|
||||
X_DSENVOLOPEDESC Xb_EnvolopeDesc;
|
||||
X_DSVOICEPROPS Xb_VoiceProperties;
|
||||
DWORD Xb_Frequency;
|
||||
DWORD Xb_Flags;
|
||||
};
|
||||
|
||||
struct XbHybridDSBuffer : DSBUFFER_S::DSBUFFER_I {
|
||||
EmuDirectSoundBuffer* emuDSBuffer;
|
||||
};
|
||||
|
||||
struct SharedDSBuffer : DSBUFFER_S {
|
||||
SharedDSBuffer(bool is3D) : DSBUFFER_S(is3D) {
|
||||
emuDSBuffer = new EmuDirectSoundBuffer();
|
||||
}
|
||||
EmuDirectSoundBuffer* emuDSBuffer;
|
||||
};
|
||||
|
||||
//Custom flags (4 bytes support up to 31 shifts,starting from 0)
|
||||
#define DSE_FLAG_PCM (1 << 0)
|
||||
|
@ -188,7 +195,7 @@ class X_CDirectSoundStream
|
|||
{
|
||||
public:
|
||||
// construct vtable (or grab ptr to existing)
|
||||
X_CDirectSoundStream() : pVtbl(&vtbl) { pMcpxStream = new X_CMcpxStream(this); };
|
||||
X_CDirectSoundStream(bool is3D) : pVtbl(&vtbl), Xb_Voice(is3D) { pMcpxStream = new X_CMcpxStream(this); };
|
||||
|
||||
private:
|
||||
// vtable (cached by each instance, via constructor)
|
||||
|
@ -243,6 +250,8 @@ class X_CDirectSoundStream
|
|||
#endif
|
||||
|
||||
public:
|
||||
// Placeholder until have positive offset
|
||||
CDirectSoundVoice Xb_Voice;
|
||||
// cached data
|
||||
LPDIRECTSOUNDBUFFER8 EmuDirectSoundBuffer8;
|
||||
LPDIRECTSOUND3DBUFFER8 EmuDirectSound3DBuffer8;
|
||||
|
@ -268,7 +277,6 @@ class X_CDirectSoundStream
|
|||
DWORD Xb_dwHeadroom;
|
||||
X_DSENVOLOPEDESC Xb_EnvolopeDesc;
|
||||
X_DSVOICEPROPS Xb_VoiceProperties;
|
||||
DWORD Xb_Frequency;
|
||||
DWORD Host_dwLastWritePos;
|
||||
DWORD Xb_Flags;
|
||||
DWORD Xb_Status;
|
||||
|
@ -481,7 +489,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetMixBinHeadroom)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwMixBinMask
|
||||
);
|
||||
|
||||
|
@ -490,7 +498,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBins)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwMixBinMask,
|
||||
const LONG* alVolumes
|
||||
);
|
||||
|
@ -500,7 +508,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_12)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMixBinVolumes_8)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
X_LPDSMIXBINS pMixBins
|
||||
);
|
||||
|
||||
|
@ -551,10 +559,10 @@ HRESULT WINAPI EMUPATCH(CDirectSound_CommitDeferredSettings)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer)
|
||||
(
|
||||
LPDIRECTSOUND8 pThis,
|
||||
X_DSBUFFERDESC* pdsbd,
|
||||
X_CDirectSoundBuffer** ppBuffer,
|
||||
LPUNKNOWN pUnkOuter
|
||||
LPDIRECTSOUND8 pThis,
|
||||
X_DSBUFFERDESC* pdsbd,
|
||||
XbHybridDSBuffer** ppBuffer,
|
||||
LPUNKNOWN pUnkOuter
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -562,8 +570,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_CreateSoundBuffer)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer)
|
||||
(
|
||||
X_DSBUFFERDESC* pdsbd,
|
||||
X_CDirectSoundBuffer** ppBuffer
|
||||
X_DSBUFFERDESC* pdsbd,
|
||||
XbHybridDSBuffer** ppBuffer
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -571,9 +579,9 @@ HRESULT WINAPI EMUPATCH(DirectSoundCreateBuffer)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
LPVOID pvBufferData,
|
||||
DWORD dwBufferBytes
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LPVOID pvBufferData,
|
||||
DWORD dwBufferBytes
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -581,9 +589,9 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetBufferData)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
DWORD dwPlayStart,
|
||||
DWORD dwPlayLength
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwPlayStart,
|
||||
DWORD dwPlayLength
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -591,7 +599,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPlayRegion)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwOffset,
|
||||
DWORD dwBytes,
|
||||
LPVOID* ppvAudioPtr1,
|
||||
|
@ -605,7 +613,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Lock)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LPVOID ppvAudioPtr1,
|
||||
DWORD pdwAudioBytes1,
|
||||
LPVOID ppvAudioPtr2,
|
||||
|
@ -617,7 +625,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Unlock)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwHeadroom
|
||||
);
|
||||
|
||||
|
@ -626,7 +634,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetHeadroom)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwLoopStart,
|
||||
DWORD dwLoopLength
|
||||
);
|
||||
|
@ -636,7 +644,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLoopRegion)
|
|||
// ******************************************************************
|
||||
ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis
|
||||
XbHybridDSBuffer* pHybridThis
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -644,7 +652,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_Release)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LONG lPitch
|
||||
);
|
||||
|
||||
|
@ -653,7 +661,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPitch)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LPDWORD pdwStatus
|
||||
);
|
||||
|
||||
|
@ -662,7 +670,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetStatus)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LONG lVolume
|
||||
);
|
||||
|
||||
|
@ -671,7 +679,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwNewPosition
|
||||
);
|
||||
|
||||
|
@ -680,7 +688,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetCurrentPosition)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
PDWORD pdwCurrentPlayCursor,
|
||||
PDWORD pdwCurrentWriteCursor
|
||||
);
|
||||
|
@ -690,7 +698,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetCurrentPosition)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis
|
||||
XbHybridDSBuffer* pHybridThis
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -698,7 +706,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Stop)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx)
|
||||
(
|
||||
X_CDirectSoundBuffer *pBuffer,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
REFERENCE_TIME rtTimeStamp,
|
||||
DWORD dwFlags
|
||||
);
|
||||
|
@ -708,7 +716,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_StopEx)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwReserved1,
|
||||
DWORD dwReserved2,
|
||||
DWORD dwFlags
|
||||
|
@ -719,7 +727,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Play)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx)
|
||||
(
|
||||
X_CDirectSoundBuffer* pBuffer,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
REFERENCE_TIME rtTimeStamp,
|
||||
DWORD dwFlags
|
||||
);
|
||||
|
@ -729,7 +737,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PlayEx)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LONG lVolume
|
||||
);
|
||||
|
||||
|
@ -738,7 +746,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVolume)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFrequency)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwFrequency
|
||||
);
|
||||
|
||||
|
@ -972,7 +980,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetMixBins)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT flMaxDistance,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -982,7 +990,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMaxDistance)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT flMaxDistance,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -992,7 +1000,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMinDistance)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT flRolloffFactor,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1002,7 +1010,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffFactor)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT flDistanceFactor,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1012,7 +1020,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDistanceFactor)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwInsideConeAngle,
|
||||
DWORD dwOutsideConeAngle,
|
||||
DWORD dwApply
|
||||
|
@ -1023,7 +1031,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeAngles)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT x,
|
||||
FLOAT y,
|
||||
FLOAT z,
|
||||
|
@ -1035,7 +1043,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOrientation)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LONG lConeOutsideVolume,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1045,7 +1053,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetConeOutsideVolume)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT x,
|
||||
FLOAT y,
|
||||
FLOAT z,
|
||||
|
@ -1057,7 +1065,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetPosition)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT x,
|
||||
FLOAT y,
|
||||
FLOAT z,
|
||||
|
@ -1069,7 +1077,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetVelocity)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
FLOAT flDopplerFactor,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1079,7 +1087,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetDopplerFactor)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
X_DSI3DL2BUFFER* pds3db,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1090,7 +1098,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetI3DL2Source)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode)
|
||||
(
|
||||
X_CDirectSoundBuffer* pBuffer,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwMode,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1100,7 +1108,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetMode)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFormat)
|
||||
(
|
||||
X_CDirectSoundBuffer *pBuffer,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LPCWAVEFORMATEX pwfxFormat
|
||||
);
|
||||
|
||||
|
@ -1129,8 +1137,8 @@ void WINAPI EMUPATCH(DirectSoundUseLightHRTF4Channel)(void);
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetLFO)
|
||||
(
|
||||
LPDIRECTSOUNDBUFFER8 pThis,
|
||||
LPCDSLFODESC pLFODesc
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LPCDSLFODESC pLFODesc
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1157,7 +1165,7 @@ VOID WINAPI EMUPATCH(XAudioCreateAdpcmFormat)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetRolloffCurve)
|
||||
(
|
||||
LPDIRECTSOUNDBUFFER8 pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
const FLOAT* pflPoints,
|
||||
DWORD dwPointCount,
|
||||
DWORD dwApply
|
||||
|
@ -1186,7 +1194,7 @@ HRESULT WINAPI EMUPATCH(IDirectSound_EnableHeadphones)
|
|||
// ******************************************************************
|
||||
ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis
|
||||
XbHybridDSBuffer* pHybridThis
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1194,7 +1202,7 @@ ULONG WINAPI EMUPATCH(IDirectSoundBuffer_AddRef)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwPause
|
||||
);
|
||||
|
||||
|
@ -1203,7 +1211,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Pause)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_PauseEx)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
REFERENCE_TIME rtTimestamp,
|
||||
DWORD dwPause
|
||||
);
|
||||
|
@ -1263,8 +1271,8 @@ HRESULT WINAPI EMUPATCH(XAudioDownloadEffectsImage)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetFilter)
|
||||
(
|
||||
LPVOID pThis,
|
||||
X_DSFILTERDESC* pFilterDesc
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
X_DSFILTERDESC* pFilterDesc
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1333,7 +1341,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetI3DL2Source)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetAllParameters)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
X_DS3DBUFFER* pc3DBufferParameters,
|
||||
DWORD dwApply
|
||||
);
|
||||
|
@ -1352,8 +1360,8 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetFormat)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
X_CDirectSoundBuffer* pOutputBuffer
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
XbHybridDSBuffer* pOutputBuffer
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1362,7 +1370,7 @@ HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetOutputBuffer)
|
|||
HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetOutputBuffer)
|
||||
(
|
||||
X_CDirectSoundStream* pThis,
|
||||
X_CDirectSoundBuffer* pOutputBuffer
|
||||
XbHybridDSBuffer* pOutputBuffer
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1389,7 +1397,7 @@ HRESULT WINAPI EMUPATCH(XWaveFileCreateMediaObject)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetEG)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
X_DSENVOLOPEDESC* pEnvelopeDesc
|
||||
);
|
||||
|
||||
|
@ -1410,8 +1418,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_GetEffectData)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_SetNotificationPositions)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
DWORD dwNotifyCount,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwNotifyCount,
|
||||
LPCDSBPOSITIONNOTIFY paNotifies
|
||||
);
|
||||
|
||||
|
@ -1444,8 +1452,8 @@ HRESULT WINAPI EMUPATCH(IDirectSound_SetEffectData)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Use3DVoiceData)
|
||||
(
|
||||
LPVOID pThis,
|
||||
LPUNKNOWN pUnknown
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
LPUNKNOWN pUnknown
|
||||
);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1597,7 +1605,7 @@ HRESULT WINAPI EMUPATCH(CDirectSoundStream_SetDopplerFactor)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_GetVoiceProperties)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
OUT X_DSVOICEPROPS* pVoiceProps);
|
||||
|
||||
// ******************************************************************
|
||||
|
@ -1696,7 +1704,7 @@ VOID WINAPI EMUPATCH(CDirectSound3DCalculator_GetVoiceData)
|
|||
// ******************************************************************
|
||||
HRESULT WINAPI EMUPATCH(IDirectSoundBuffer_Set3DVoiceData)
|
||||
(
|
||||
X_CDirectSoundBuffer* pThis,
|
||||
XbHybridDSBuffer* pHybridThis,
|
||||
DWORD a2);
|
||||
|
||||
// ******************************************************************
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -45,7 +45,7 @@ extern std::recursive_mutex g_DSoundMutex;
|
|||
// Xbox maximum synch playback audio
|
||||
#define DSOUND_MAX_SYNCHPLAYBACK_AUDIO 29
|
||||
|
||||
#define vector_ds_buffer std::vector<XTL::X_CDirectSoundBuffer*>
|
||||
#define vector_ds_buffer std::vector<XTL::XbHybridDSBuffer*>
|
||||
#define vector_ds_stream std::vector<XTL::X_CDirectSoundStream*>
|
||||
extern vector_ds_buffer g_pDSoundBufferCache;
|
||||
extern vector_ds_stream g_pDSoundStreamCache;
|
||||
|
|
|
@ -254,7 +254,8 @@ static inline void GeneratePCMFormat(
|
|||
LPVOID* X_BufferCache,
|
||||
DWORD &X_BufferCacheSize,
|
||||
XTL::X_DSVOICEPROPS& Xb_VoiceProperties,
|
||||
XTL::X_LPDSMIXBINS mixbins_output)
|
||||
XTL::X_LPDSMIXBINS mixbins_output,
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
bool bIsSpecial = false;
|
||||
|
||||
|
@ -396,7 +397,6 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT
|
|||
pThis->Xb_dwHeadroom = 600; /* default for 2D voice */ \
|
||||
pThis->Xb_EnvolopeDesc = { 0 }; \
|
||||
InitVoiceProperties(pThis->Xb_VoiceProperties); /* The rest will initialize in GeneratePCMFormat to GenerateMixBinDefault. */ \
|
||||
pThis->Xb_Frequency = XTL_DSXFREQUENCY_ORIGINAL; \
|
||||
pThis->Xb_Flags = Xb_dwFlags;
|
||||
//pThis->EmuBufferDesc = { 0 }; // Enable this when become necessary.
|
||||
/*
|
||||
|
@ -405,7 +405,7 @@ static inline void DSound3DBufferCreate(LPDIRECTSOUNDBUFFER8 pDSBuffer, LPDIRECT
|
|||
pThis->EmuLockPtr2 = xbnullptr; \
|
||||
pThis->EmuLockBytes2 = 0; \ */
|
||||
|
||||
static inline void DSoundBufferRegionSetDefault(XTL::X_CDirectSoundBuffer *pThis) {
|
||||
static inline void DSoundBufferRegionSetDefault(XTL::EmuDirectSoundBuffer *pThis) {
|
||||
pThis->EmuBufferToggle = XTL::X_DSB_TOGGLE_DEFAULT;
|
||||
pThis->EmuRegionLoopStartOffset = 0;
|
||||
pThis->EmuRegionLoopLength = 0;
|
||||
|
@ -419,7 +419,7 @@ static inline void DSoundBufferTransferSettings(
|
|||
LPDIRECTSOUNDBUFFER8 &pDSBufferNew,
|
||||
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferOld,
|
||||
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew,
|
||||
DWORD Xb_Frequency)
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
LONG lVolume, lPan;
|
||||
DS3DBUFFER ds3dBuffer;
|
||||
|
@ -428,7 +428,9 @@ static inline void DSoundBufferTransferSettings(
|
|||
return;
|
||||
}
|
||||
|
||||
pDSBufferNew->SetFrequency(Xb_Frequency);
|
||||
// if sync current frequency used (then use pitch only).
|
||||
uint32_t freq = XTL::converter_pitch2freq(Xb_Voice->GetPitch(Xb_Voice));
|
||||
pDSBufferNew->SetFrequency(freq);
|
||||
|
||||
pDSBufferOld->GetVolume(&lVolume);
|
||||
pDSBufferNew->SetVolume(lVolume);
|
||||
|
@ -449,7 +451,7 @@ static inline void DSoundBufferReCreate(
|
|||
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer,
|
||||
LPDIRECTSOUNDBUFFER8 &pDSBufferNew,
|
||||
LPDIRECTSOUND3DBUFFER8 &pDS3DBufferNew,
|
||||
DWORD Xb_Frequency) {
|
||||
XTL::CDirectSoundVoice* Xb_Voice) {
|
||||
|
||||
|
||||
DSoundBufferCreate(&DSBufferDesc, pDSBufferNew);
|
||||
|
@ -458,7 +460,7 @@ static inline void DSoundBufferReCreate(
|
|||
DSound3DBufferCreate(pDSBufferNew, pDS3DBufferNew);
|
||||
}
|
||||
|
||||
DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Frequency);
|
||||
DSoundBufferTransferSettings(pDSBuffer, pDSBufferNew, pDS3DBuffer, pDS3DBufferNew, Xb_Voice);
|
||||
}
|
||||
|
||||
static inline void DSoundBufferRelease(
|
||||
|
@ -484,10 +486,11 @@ static inline void DSoundBufferRelease(
|
|||
}
|
||||
|
||||
static inline void DSoundBufferResizeSetSize(
|
||||
XTL::X_CDirectSoundBuffer* pThis,
|
||||
XTL::XbHybridDSBuffer* pHybridThis,
|
||||
HRESULT &hRet,
|
||||
DWORD Xb_dwByteLength) {
|
||||
|
||||
XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer;
|
||||
// General return OK, nothing needs to set as invalid for now.
|
||||
hRet = DS_OK;
|
||||
|
||||
|
@ -508,7 +511,7 @@ static inline void DSoundBufferResizeSetSize(
|
|||
LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr;
|
||||
|
||||
DSoundBufferReCreate(pThis->EmuDirectSoundBuffer8, pThis->EmuBufferDesc, pThis->EmuDirectSound3DBuffer8,
|
||||
pDSBufferNew, pDS3DBufferNew, pThis->Xb_Frequency);
|
||||
pDSBufferNew, pDS3DBufferNew, pHybridThis->p_CDSVoice);
|
||||
|
||||
// release old buffer
|
||||
DSoundBufferRelease(pThis->EmuDirectSoundBuffer8, pThis->EmuDirectSound3DBuffer8, refCount);
|
||||
|
@ -522,13 +525,14 @@ static inline void DSoundBufferResizeSetSize(
|
|||
}
|
||||
|
||||
static inline void DSoundBufferResizeUpdate(
|
||||
XTL::X_CDirectSoundBuffer* pThis,
|
||||
XTL::XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwPlayFlags,
|
||||
HRESULT &hRet,
|
||||
DWORD Xb_dwStartOffset,
|
||||
DWORD Xb_dwByteLength) {
|
||||
|
||||
DSoundBufferResizeSetSize(pThis, hRet, Xb_dwByteLength);
|
||||
XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer;
|
||||
DSoundBufferResizeSetSize(pHybridThis, hRet, Xb_dwByteLength);
|
||||
|
||||
hRet = pThis->EmuDirectSoundBuffer8->Lock(0, 0, &pThis->Host_lock.pLockPtr1, &pThis->Host_lock.dwLockBytes1,
|
||||
nullptr, nullptr, DSBLOCK_ENTIREBUFFER);
|
||||
|
@ -546,11 +550,13 @@ static inline void DSoundBufferResizeUpdate(
|
|||
}
|
||||
|
||||
static inline void DSoundBufferRegionCurrentLocation(
|
||||
XTL::X_CDirectSoundBuffer* pThis,
|
||||
XTL::XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwPlayFlags,
|
||||
HRESULT &hRet,
|
||||
DWORD &Xb_dwStartOffset,
|
||||
DWORD &Xb_dwByteLength) {
|
||||
DWORD &Xb_dwByteLength)
|
||||
{
|
||||
XTL::EmuDirectSoundBuffer* pThis = pHybridThis->emuDSBuffer;
|
||||
if ((dwPlayFlags & X_DSBPLAY_LOOPING) > 0) {
|
||||
Xb_dwStartOffset = pThis->EmuRegionPlayStartOffset + pThis->EmuRegionLoopStartOffset;
|
||||
|
||||
|
@ -577,7 +583,7 @@ static inline void DSoundBufferRegionCurrentLocation(
|
|||
}
|
||||
|
||||
static inline void DSoundBufferUpdate(
|
||||
XTL::X_CDirectSoundBuffer* pThis,
|
||||
XTL::XbHybridDSBuffer* pHybridThis,
|
||||
DWORD dwPlayFlags,
|
||||
HRESULT &hRet) {
|
||||
|
||||
|
@ -585,24 +591,24 @@ static inline void DSoundBufferUpdate(
|
|||
DWORD Xb_dwByteLength;
|
||||
DWORD Xb_dwStartOffset;
|
||||
|
||||
DSoundBufferRegionCurrentLocation(pThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
|
||||
DSoundBufferRegionCurrentLocation(pHybridThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
|
||||
|
||||
DSoundBufferResizeUpdate(pThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
|
||||
DSoundBufferResizeUpdate(pHybridThis, dwPlayFlags, hRet, Xb_dwStartOffset, Xb_dwByteLength);
|
||||
}
|
||||
|
||||
static inline void DSoundBufferReplace(
|
||||
static inline void DSoundBufferRegenWithNewFormat(
|
||||
LPDIRECTSOUNDBUFFER8 &pDSBuffer,
|
||||
DSBUFFERDESC &DSBufferDesc,
|
||||
DWORD PlayFlags,
|
||||
LPDIRECTSOUND3DBUFFER8 &pDS3DBuffer,
|
||||
DWORD Xb_Frequency)
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
DWORD refCount, dwPlayCursor, dwStatus;
|
||||
LPDIRECTSOUNDBUFFER8 pDSBufferNew = nullptr;
|
||||
LPDIRECTSOUND3DBUFFER8 pDS3DBufferNew = nullptr;
|
||||
|
||||
DSoundBufferReCreate(pDSBuffer, DSBufferDesc, pDS3DBuffer,
|
||||
pDSBufferNew, pDS3DBufferNew, Xb_Frequency);
|
||||
pDSBufferNew, pDS3DBufferNew, Xb_Voice);
|
||||
|
||||
HRESULT hRet = pDSBuffer->GetStatus(&dwStatus);
|
||||
|
||||
|
@ -1082,15 +1088,17 @@ static inline HRESULT HybridDirectSoundBuffer_SetFormat(
|
|||
DWORD &X_BufferCacheSize,
|
||||
XTL::X_DSVOICEPROPS &Xb_VoiceProperties,
|
||||
XTL::X_LPDSMIXBINS mixbins_output,
|
||||
DWORD Xb_Frequency)
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
pDSBuffer->Stop();
|
||||
|
||||
if (X_BufferAllocate) {
|
||||
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, X_BufferCacheSize, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output);
|
||||
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, X_BufferCacheSize,
|
||||
xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output, Xb_Voice);
|
||||
// Don't allocate for DS Stream class, it is using straight from the source.
|
||||
} else {
|
||||
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, 0, xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output);
|
||||
GeneratePCMFormat(BufferDesc, Xb_pwfxFormat, Xb_flags, dwEmuFlags, 0,
|
||||
xbnullptr, X_BufferCacheSize, Xb_VoiceProperties, mixbins_output, Xb_Voice);
|
||||
}
|
||||
HRESULT hRet = DS_OK;
|
||||
if ((void*)g_pDSoundPrimaryBuffer == (void*)pDSBuffer) {
|
||||
|
@ -1101,28 +1109,31 @@ static inline HRESULT HybridDirectSoundBuffer_SetFormat(
|
|||
// Allocate at least 5 second worth of bytes in PCM format.
|
||||
BufferDesc.dwBufferBytes = BufferDesc.lpwfxFormat->nAvgBytesPerSec * 5;
|
||||
}
|
||||
DSoundBufferReplace(pDSBuffer, BufferDesc, dwPlayFlags, pDS3DBuffer, Xb_Frequency);
|
||||
DSoundBufferRegenWithNewFormat(pDSBuffer, BufferDesc, dwPlayFlags, pDS3DBuffer, Xb_Voice);
|
||||
}
|
||||
|
||||
RETURN_RESULT_CHECK(hRet);
|
||||
}
|
||||
|
||||
static HRESULT HybridDirectSoundBuffer_SetPitch(LPDIRECTSOUNDBUFFER8, LONG, XTL::CDirectSoundVoice*);
|
||||
|
||||
//IDirectSoundStream
|
||||
//IDirectSoundBuffer
|
||||
static inline HRESULT HybridDirectSoundBuffer_SetFrequency(
|
||||
LPDIRECTSOUNDBUFFER8 pDSBuffer,
|
||||
DWORD dwFrequency,
|
||||
DWORD &Xb_Frequency)
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
HRESULT hRet = S_OK;
|
||||
|
||||
Xb_Frequency = dwFrequency;
|
||||
hRet = pDSBuffer->SetFrequency(dwFrequency);
|
||||
int32_t pitch = XTL::converter_freq2pitch((dwFrequency!=0 ? dwFrequency : Xb_Voice->GetFrequencyDefault(Xb_Voice)));
|
||||
|
||||
hRet = HybridDirectSoundBuffer_SetPitch(pDSBuffer, pitch, Xb_Voice);
|
||||
|
||||
RETURN_RESULT_CHECK(hRet);
|
||||
}
|
||||
|
||||
static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD);
|
||||
static HRESULT HybridDirectSoundBuffer_SetVolume(LPDIRECTSOUNDBUFFER8, LONG, DWORD, LPLONG, LONG, DWORD, XTL::CDirectSoundVoice*);
|
||||
|
||||
//IDirectSoundStream
|
||||
//IDirectSoundBuffer
|
||||
|
@ -1133,7 +1144,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom(
|
|||
DWORD &Xb_dwHeadroom,
|
||||
LONG Xb_volume,
|
||||
LONG Xb_volumeMixbin,
|
||||
DWORD dwEmuFlags)
|
||||
DWORD dwEmuFlags,
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
HRESULT hRet;
|
||||
if (dwHeadroom > 10000) {
|
||||
|
@ -1141,7 +1153,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetHeadroom(
|
|||
} else {
|
||||
Xb_dwHeadroom = dwHeadroom;
|
||||
hRet = DS_OK;
|
||||
HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom);
|
||||
HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, dwEmuFlags, xbnullptr, Xb_volumeMixbin, dwHeadroom, Xb_Voice);
|
||||
}
|
||||
|
||||
return DS_OK;
|
||||
|
@ -1233,7 +1245,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
|
|||
DWORD EmuFlags,
|
||||
LONG Xb_volume,
|
||||
LONG &Xb_volumeMixBin,
|
||||
DWORD Xb_dwHeadroom)
|
||||
DWORD Xb_dwHeadroom,
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
HRESULT hRet = DSERR_INVALIDPARAM;
|
||||
|
||||
|
@ -1274,7 +1287,7 @@ static inline HRESULT HybridDirectSoundBuffer_SetMixBinVolumes_8(
|
|||
if (counter > 0) {
|
||||
Xb_volumeMixBin = volume / (LONG)counter;
|
||||
hRet = HybridDirectSoundBuffer_SetVolume(pDSBuffer, Xb_volume, EmuFlags, nullptr,
|
||||
Xb_volumeMixBin, Xb_dwHeadroom);
|
||||
Xb_volumeMixBin, Xb_dwHeadroom, Xb_Voice);
|
||||
} else {
|
||||
hRet = DS_OK;
|
||||
}
|
||||
|
@ -1326,27 +1339,14 @@ static inline HRESULT HybridDirectSoundBuffer_SetOutputBuffer(
|
|||
static inline HRESULT HybridDirectSoundBuffer_SetPitch(
|
||||
LPDIRECTSOUNDBUFFER8 pDSBuffer,
|
||||
LONG lPitch,
|
||||
DWORD &Xb_Frequency)
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
|
||||
Xb_Voice->SetPitch(Xb_Voice, lPitch);
|
||||
// Convert pitch back to frequency
|
||||
// NOTE: pitch = 0 is equal to 48 KHz.
|
||||
Xb_Frequency = static_cast<DWORD>(exp((lPitch / 4096.0f) * log(2)) * 48000.0f);
|
||||
uint32_t setFrequency = XTL::converter_pitch2freq(lPitch);
|
||||
|
||||
/* For research purpose of how to convert frequency to pitch and back to frequency.
|
||||
// Edit hertz variable to see the result.
|
||||
float hertz = 12000.0f;
|
||||
|
||||
float hertzRatio = 48000.0f;
|
||||
float pitchRatio = 4096.0f;
|
||||
|
||||
// Convert hertz to pitch
|
||||
float pitch = log2(hertz / hertzRatio) * pitchRatio;
|
||||
|
||||
// Convert pitch to hertz
|
||||
hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/
|
||||
|
||||
RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(Xb_Frequency));
|
||||
RETURN_RESULT_CHECK(pDSBuffer->SetFrequency(setFrequency));
|
||||
}
|
||||
/*
|
||||
//Only has one function, this is not a requirement.
|
||||
|
@ -1431,7 +1431,8 @@ static inline HRESULT HybridDirectSoundBuffer_SetVolume(
|
|||
DWORD dwEmuFlags,
|
||||
LPLONG Xb_lpVolume,
|
||||
LONG Xb_volumeMixbin,
|
||||
DWORD Xb_dwHeadroom)
|
||||
DWORD Xb_dwHeadroom,
|
||||
XTL::CDirectSoundVoice* Xb_Voice)
|
||||
{
|
||||
// Preserve original volume
|
||||
if (Xb_lpVolume != xbnullptr) {
|
||||
|
|
|
@ -70,9 +70,9 @@ XTL::X_CDirectSoundStream::_vtbl XTL::X_CDirectSoundStream::vtbl =
|
|||
&XTL::EMUPATCH(CDirectSoundStream_Process), // 0x10
|
||||
&XTL::EMUPATCH(CDirectSoundStream_Discontinuity), // 0x14
|
||||
&XTL::EMUPATCH(CDirectSoundStream_Flush), // 0x18
|
||||
0xBEEFB003, // 0x1C
|
||||
0xBEEFB004, // 0x20
|
||||
0xBEEFB005, // 0x24
|
||||
0xBEEFB003, // 0x1C // unknown function
|
||||
0xBEEFB004, // 0x20 // DS_CRefCount_AddRef
|
||||
0xBEEFB005, // 0x24 // DS_CRefCount_Release
|
||||
0xBEEFB006, // 0x28
|
||||
0xBEEFB007, // 0x2C
|
||||
0xBEEFB008, // 0x30
|
||||
|
@ -208,8 +208,6 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
|
|||
hRet = DSERR_OUTOFMEMORY;
|
||||
*ppStream = xbnullptr;
|
||||
} else {
|
||||
// TODO: Garbage Collection
|
||||
*ppStream = new X_CDirectSoundStream();
|
||||
|
||||
DSBUFFERDESC DSBufferDesc = { 0 };
|
||||
|
||||
|
@ -230,12 +228,16 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
|
|||
DSBufferDesc.dwFlags |= DSBCAPS_CTRLPAN;
|
||||
}
|
||||
|
||||
// TODO: Garbage Collection
|
||||
*ppStream = new X_CDirectSoundStream((DSBufferDesc.dwFlags & DSBCAPS_CTRL3D) != 0);
|
||||
|
||||
DSoundBufferSetDefault((*ppStream), DSBPLAY_LOOPING, pdssd->dwFlags);
|
||||
(*ppStream)->Xb_rtFlushEx = 0LL;
|
||||
|
||||
// We have to set DSBufferDesc last due to EmuFlags must be either 0 or previously written value to preserve other flags.
|
||||
GeneratePCMFormat(DSBufferDesc, pdssd->lpwfxFormat, pdssd->dwFlags, (*ppStream)->EmuFlags, 0,
|
||||
xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput);
|
||||
xbnullptr, (*ppStream)->X_BufferCacheSize, (*ppStream)->Xb_VoiceProperties, pdssd->lpMixBinsOutput,
|
||||
&(*ppStream)->Xb_Voice);
|
||||
|
||||
// Test case: Star Wars: KotOR has one packet greater than 5 seconds worth. Increasing to 10 seconds allow stream to work until
|
||||
// another test case below proven host's buffer size does not matter since packet's size can be greater than host's buffer size.
|
||||
|
@ -276,7 +278,7 @@ HRESULT WINAPI XTL::EMUPATCH(DirectSoundCreateStream)
|
|||
|
||||
// Pre-set volume to enforce silence if one of audio codec is disabled.
|
||||
HybridDirectSoundBuffer_SetVolume((*ppStream)->EmuDirectSoundBuffer8, 0L, (*ppStream)->EmuFlags, nullptr,
|
||||
(*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom);
|
||||
(*ppStream)->Xb_VolumeMixbin, (*ppStream)->Xb_dwHeadroom, &(*ppStream)->Xb_Voice);
|
||||
|
||||
g_pDSoundStreamCache.push_back(*ppStream);
|
||||
}
|
||||
|
@ -912,7 +914,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFormat)
|
|||
pThis->EmuBufferDesc, pThis->EmuFlags, pThis->EmuPlayFlags,
|
||||
pThis->EmuDirectSound3DBuffer8, 0, pThis->X_BufferCache,
|
||||
pThis->X_BufferCacheSize, pThis->Xb_VoiceProperties,
|
||||
xbnullptr, pThis->Xb_Frequency);
|
||||
xbnullptr, &pThis->Xb_Voice);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -932,7 +934,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetFrequency)
|
|||
LOG_FUNC_ARG(dwFrequency)
|
||||
LOG_FUNC_END;
|
||||
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, pThis->Xb_Frequency);
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetFrequency(pThis->EmuDirectSoundBuffer8, dwFrequency, &pThis->Xb_Voice);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -968,7 +970,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetHeadroom)
|
|||
LOG_FUNC_END;
|
||||
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetHeadroom(pThis->EmuDirectSoundBuffer8, dwHeadroom, pThis->Xb_dwHeadroom,
|
||||
pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags);
|
||||
pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->EmuFlags, &pThis->Xb_Voice);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -1208,7 +1210,8 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8)
|
|||
LOG_FUNC_END;
|
||||
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetMixBinVolumes_8(pThis->EmuDirectSoundBuffer8, pMixBins, pThis->Xb_VoiceProperties,
|
||||
pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
|
||||
pThis->EmuFlags, pThis->Xb_Volume, pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom,
|
||||
&pThis->Xb_Voice);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -1219,7 +1222,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetMixBinVolumes_8)
|
|||
HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetOutputBuffer)
|
||||
(
|
||||
X_CDirectSoundStream* pThis,
|
||||
X_CDirectSoundBuffer* pOutputBuffer)
|
||||
XbHybridDSBuffer* pOutputBuffer)
|
||||
{
|
||||
DSoundMutexGuardLock;
|
||||
|
||||
|
@ -1252,7 +1255,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetPitch)
|
|||
LOG_FUNC_ARG(lPitch)
|
||||
LOG_FUNC_END;
|
||||
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, pThis->Xb_Frequency);
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetPitch(pThis->EmuDirectSoundBuffer8, lPitch, &pThis->Xb_Voice);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
@ -1388,7 +1391,7 @@ HRESULT WINAPI XTL::EMUPATCH(CDirectSoundStream_SetVolume)
|
|||
LOG_FUNC_END;
|
||||
|
||||
HRESULT hRet = HybridDirectSoundBuffer_SetVolume(pThis->EmuDirectSoundBuffer8, lVolume, pThis->EmuFlags, &pThis->Xb_Volume,
|
||||
pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom);
|
||||
pThis->Xb_VolumeMixbin, pThis->Xb_dwHeadroom, &pThis->Xb_Voice);
|
||||
|
||||
return hRet;
|
||||
}
|
||||
|
|
|
@ -369,6 +369,30 @@ struct X_DSVOICEPROPS {
|
|||
LONG lI3DL2DirectVolume;
|
||||
LONG lI3DL2RoomVolume;
|
||||
};
|
||||
|
||||
// Convert frequency to pitch helper
|
||||
static inline int32_t converter_freq2pitch(uint32_t freq) {
|
||||
// NOTE: pitch = 0 is equal to 48 KHz.
|
||||
/* For research purpose of how to convert frequency to pitch and back to frequency.
|
||||
// Edit hertz variable to see the result.
|
||||
float hertz = 12000.0f;
|
||||
|
||||
float hertzRatio = 48000.0f;
|
||||
float pitchRatio = 4096.0f;
|
||||
|
||||
// Convert hertz to pitch
|
||||
float pitch = log2(hertz / hertzRatio) * pitchRatio;
|
||||
|
||||
// Convert pitch to hertz
|
||||
hertz = exp((pitch / pitchRatio) * log(2)) * hertzRatio;*/
|
||||
return static_cast<int32_t>(log2(freq / 48000.0f) * 4096.0f);
|
||||
}
|
||||
|
||||
// Convert pitch to frequency helper
|
||||
static inline uint32_t converter_pitch2freq(int32_t pitch) {
|
||||
//* See research documentation above for conversion example.
|
||||
return static_cast<uint32_t>(exp((pitch / 4096.0f) * log(2)) * 48000.0f);
|
||||
}
|
||||
|
||||
} // end of namespace XTL
|
||||
|
||||
|
|
|
@ -0,0 +1,272 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * This file is part of the Cxbx project.
|
||||
// *
|
||||
// * Cxbx and Cxbe are free software; you can redistribute them
|
||||
// * and/or modify them under the terms of the GNU General Public
|
||||
// * License as published by the Free Software Foundation; either
|
||||
// * version 2 of the license, or (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have recieved a copy of the GNU General Public License
|
||||
// * along with this program; see the file COPYING.
|
||||
// * If not, write to the Free Software Foundation, Inc.,
|
||||
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// *
|
||||
// * (c) 2020 RadWolfie
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#include "common\Settings.hpp" // for g_LibVersion_DSOUND
|
||||
#include "XbInternalStruct.hpp"
|
||||
|
||||
// Interface for get format
|
||||
void GetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format)
|
||||
{
|
||||
format.audio_codec = u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec;
|
||||
format.nChannels = u.settings_4034_lower.p_audio_format->wfx.nChannels;
|
||||
format.cbSize = u.settings_4034_lower.p_audio_format->wfx.cbSize;
|
||||
format.nSamplesPerSec = u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec;
|
||||
format.bitsPerSample = u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample;
|
||||
}
|
||||
void GetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format)
|
||||
{
|
||||
format.audio_codec = u.settings_4039_only.audio_codec;
|
||||
format.nChannels = u.settings_4039_only.nChannels;
|
||||
format.cbSize = u.settings_4039_only.cbSize;
|
||||
format.nSamplesPerSec = u.settings_4039_only.nSamplesPerSec_default;
|
||||
format.bitsPerSample = u.settings_4039_only.bitsPerSample;
|
||||
}
|
||||
void GetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format& format)
|
||||
{
|
||||
format.audio_codec = u.settings_4134_upper.audio_codec;
|
||||
format.nChannels = u.settings_4134_upper.nChannels;
|
||||
format.cbSize = u.settings_4134_upper.cbSize;
|
||||
format.nSamplesPerSec = u.settings_4134_upper.nSamplesPerSec_default;
|
||||
format.bitsPerSample = u.settings_4134_upper.bitsPerSample;
|
||||
}
|
||||
|
||||
// Interface for set format
|
||||
void SetFormat_4034_lower(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format)
|
||||
{
|
||||
u.settings_4034_lower.p_audio_format->wfx.wFormatTag = format.audio_codec;
|
||||
u.settings_4034_lower.p_audio_format->wfx.nChannels = static_cast<uint16_t>(format.nChannels);
|
||||
u.settings_4034_lower.p_audio_format->wfx.cbSize = static_cast<uint16_t>(format.cbSize);
|
||||
u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec = format.nSamplesPerSec;
|
||||
u.settings_4034_lower.p_audio_format->wfx.wBitsPerSample = static_cast<uint16_t>(format.bitsPerSample);
|
||||
if (format.audio_codec == WAVE_FORMAT_XBOX_ADPCM) {
|
||||
u.settings_4034_lower.p_audio_format->wSamplesPerBlock = 64;
|
||||
}
|
||||
u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec);
|
||||
}
|
||||
void SetFormat_4039_only(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format)
|
||||
{
|
||||
u.settings_4039_only.audio_codec = format.audio_codec;
|
||||
u.settings_4039_only.nChannels = format.nChannels;
|
||||
u.settings_4039_only.cbSize = format.cbSize;
|
||||
u.settings_4039_only.nSamplesPerSec_default = format.nSamplesPerSec;
|
||||
u.settings_4039_only.bitsPerSample = format.bitsPerSample;
|
||||
u.settings_4039_only.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec);
|
||||
}
|
||||
void SetFormat_4134_upper(XTL::CDirectSoundVoice::_u& u, XTL::audio_format format)
|
||||
{
|
||||
u.settings_4134_upper.audio_codec = static_cast<uint16_t>(format.audio_codec);
|
||||
u.settings_4134_upper.nChannels = static_cast<uint8_t>(format.nChannels);
|
||||
u.settings_4134_upper.cbSize = static_cast<uint8_t>(format.cbSize);
|
||||
u.settings_4134_upper.nSamplesPerSec_default = format.nSamplesPerSec;
|
||||
u.settings_4134_upper.bitsPerSample = format.bitsPerSample;
|
||||
u.settings_4134_upper.pitch = XTL::converter_freq2pitch(format.nSamplesPerSec);
|
||||
}
|
||||
|
||||
// Interface for get frequency
|
||||
uint32_t GetFrequencyDefault_4034_lower(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4034_lower.p_audio_format->wfx.nSamplesPerSec;
|
||||
}
|
||||
uint32_t GetFrequencyDefault_4039_only(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4039_only.nSamplesPerSec_default;
|
||||
}
|
||||
uint32_t GetFrequencyDefault_4134_upper(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4134_upper.nSamplesPerSec_default;
|
||||
}
|
||||
|
||||
// Interface for get pitch
|
||||
int32_t GetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4034_lower.pitch;
|
||||
}
|
||||
int32_t GetPitch_4039_only(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4039_only.pitch;
|
||||
}
|
||||
int32_t GetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4134_upper.pitch;
|
||||
}
|
||||
|
||||
// Interface for set pitch
|
||||
void SetPitch_4034_lower(XTL::CDirectSoundVoice::_u& u, int32_t pitch)
|
||||
{
|
||||
u.settings_4034_lower.pitch = pitch;
|
||||
}
|
||||
void SetPitch_4039_only(XTL::CDirectSoundVoice::_u& u, int32_t pitch)
|
||||
{
|
||||
u.settings_4039_only.pitch = pitch;
|
||||
}
|
||||
void SetPitch_4134_upper(XTL::CDirectSoundVoice::_u& u, int32_t pitch)
|
||||
{
|
||||
u.settings_4134_upper.pitch = pitch;
|
||||
}
|
||||
|
||||
// Interface for get volume
|
||||
uint32_t GetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4034_lower.volume;
|
||||
}
|
||||
uint32_t GetVolume_4039_only(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4039_only.volume;
|
||||
}
|
||||
uint32_t GetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4134_upper.volume;
|
||||
}
|
||||
|
||||
void SetVolume_calc(uint32_t& cur_volume, uint32_t headroom, uint32_t set_volume)
|
||||
{
|
||||
cur_volume = set_volume - headroom;
|
||||
}
|
||||
// Interface for set volume
|
||||
void SetVolume_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t volume)
|
||||
{
|
||||
SetVolume_calc(u.settings_4034_lower.volume, u.settings_4034_lower.headroom, volume);
|
||||
}
|
||||
void SetVolume_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t volume)
|
||||
{
|
||||
SetVolume_calc(u.settings_4039_only.volume, u.settings_4039_only.headroom, volume);
|
||||
}
|
||||
void SetVolume_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t volume)
|
||||
{
|
||||
SetVolume_calc(u.settings_4134_upper.volume, u.settings_4134_upper.headroom, volume);
|
||||
}
|
||||
|
||||
// Interface for get headroom
|
||||
uint32_t GetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4034_lower.headroom;
|
||||
}
|
||||
uint32_t GetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4039_only.headroom;
|
||||
}
|
||||
uint32_t GetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u)
|
||||
{
|
||||
return u.settings_4134_upper.headroom;
|
||||
}
|
||||
|
||||
void SetHeadroom_calc(uint32_t& cur_headroom, uint32_t& volume, uint32_t set_headroom)
|
||||
{
|
||||
volume = volume - set_headroom - cur_headroom;
|
||||
cur_headroom = set_headroom;
|
||||
}
|
||||
// Interface for set headroom
|
||||
void SetHeadroom_4034_lower(XTL::CDirectSoundVoice::_u& u, uint32_t headroom)
|
||||
{
|
||||
SetHeadroom_calc(u.settings_4034_lower.headroom, u.settings_4034_lower.volume, headroom);
|
||||
}
|
||||
void SetHeadroom_4039_only(XTL::CDirectSoundVoice::_u& u, uint32_t headroom)
|
||||
{
|
||||
SetHeadroom_calc(u.settings_4039_only.headroom, u.settings_4039_only.volume, headroom);
|
||||
}
|
||||
void SetHeadroom_4134_upper(XTL::CDirectSoundVoice::_u& u, uint32_t headroom)
|
||||
{
|
||||
SetHeadroom_calc(u.settings_4134_upper.headroom, u.settings_4134_upper.volume, headroom);
|
||||
}
|
||||
|
||||
void Init_Headroom(uint32_t& headroom, bool is3D)
|
||||
{
|
||||
headroom = is3D? 0 : 600;
|
||||
}
|
||||
void Init_4034_lower(XTL::CDirectSoundVoice::_u::_settings_4034_lower& settings, bool is3D)
|
||||
{
|
||||
Init_Headroom(settings.headroom, is3D);
|
||||
settings.volume = 0 - settings.headroom;
|
||||
}
|
||||
void Init_4039_only(XTL::CDirectSoundVoice::_u::_settings_4039_only& settings, bool is3D)
|
||||
{
|
||||
Init_Headroom(settings.headroom, is3D);
|
||||
settings.volume = 0 - settings.headroom;
|
||||
}
|
||||
void Init_4134_upper(XTL::CDirectSoundVoice::_u::_settings_4134_upper& settings, bool is3D)
|
||||
{
|
||||
Init_Headroom(settings.headroom, is3D);
|
||||
settings.volume = 0 - settings.headroom;
|
||||
}
|
||||
|
||||
XTL::CDirectSoundVoice::CDirectSoundVoice(bool is3D)
|
||||
{
|
||||
memset(u.settings_interface.unknown_08, 0, sizeof(u.settings_interface));
|
||||
|
||||
if (g_LibVersion_DSOUND < 4039) {
|
||||
u.settings_4034_lower.p_audio_format = new XBOXADPCMWAVEFORMAT;
|
||||
memset(&u.settings_4034_lower.p_audio_format->wfx, 0, sizeof(XBOXADPCMWAVEFORMAT));
|
||||
|
||||
Init_4034_lower(u.settings_4034_lower, is3D);
|
||||
|
||||
funcs.GetFormat = GetFormat_4034_lower;
|
||||
funcs.SetFormat = SetFormat_4034_lower;
|
||||
funcs.GetFrequencyDefault = GetFrequencyDefault_4034_lower;
|
||||
funcs.GetPitch = GetPitch_4034_lower;
|
||||
funcs.SetPitch = SetPitch_4034_lower;
|
||||
funcs.GetVolume = GetVolume_4034_lower;
|
||||
funcs.SetVolume = SetVolume_4034_lower;
|
||||
funcs.GetHeadroom = GetHeadroom_4034_lower;
|
||||
funcs.SetHeadroom = SetHeadroom_4034_lower;
|
||||
}
|
||||
else if (g_LibVersion_DSOUND == 4039) {
|
||||
|
||||
Init_4039_only(u.settings_4039_only, is3D);
|
||||
|
||||
funcs.GetFormat = GetFormat_4039_only;
|
||||
funcs.SetFormat = SetFormat_4039_only;
|
||||
funcs.GetFrequencyDefault = GetFrequencyDefault_4039_only;
|
||||
funcs.GetPitch = GetPitch_4039_only;
|
||||
funcs.SetPitch = SetPitch_4039_only;
|
||||
funcs.GetVolume = GetVolume_4039_only;
|
||||
funcs.SetVolume = SetVolume_4039_only;
|
||||
funcs.GetHeadroom = GetHeadroom_4039_only;
|
||||
funcs.SetHeadroom = SetHeadroom_4039_only;
|
||||
}
|
||||
else {
|
||||
|
||||
Init_4134_upper(u.settings_4134_upper, is3D);
|
||||
|
||||
funcs.GetFormat = GetFormat_4134_upper;
|
||||
funcs.SetFormat = SetFormat_4134_upper;
|
||||
funcs.GetFrequencyDefault = GetFrequencyDefault_4134_upper;
|
||||
funcs.GetPitch = GetPitch_4134_upper;
|
||||
funcs.SetPitch = SetPitch_4134_upper;
|
||||
funcs.GetVolume = GetVolume_4134_upper;
|
||||
funcs.SetVolume = SetVolume_4134_upper;
|
||||
funcs.GetHeadroom = GetHeadroom_4134_upper;
|
||||
funcs.SetHeadroom = SetHeadroom_4134_upper;
|
||||
}
|
||||
}
|
||||
|
||||
XTL::CDirectSoundVoice::~CDirectSoundVoice()
|
||||
{
|
||||
if (g_LibVersion_DSOUND < 4039) {
|
||||
if (!u.settings_4034_lower.p_audio_format) {
|
||||
delete u.settings_4034_lower.p_audio_format;
|
||||
u.settings_4034_lower.p_audio_format = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * This file is part of the Cxbx project.
|
||||
// *
|
||||
// * Cxbx and Cxbe are free software; you can redistribute them
|
||||
// * and/or modify them under the terms of the GNU General Public
|
||||
// * License as published by the Free Software Foundation; either
|
||||
// * version 2 of the license, or (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have recieved a copy of the GNU General Public License
|
||||
// * along with this program; see the file COPYING.
|
||||
// * If not, write to the Free Software Foundation, Inc.,
|
||||
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// *
|
||||
// * (c) 2020 RadWolfie
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
|
||||
#include "XbInternalStruct.hpp"
|
||||
|
||||
XTL::CUnknownTemplate::CUnknownTemplate() { ref_count = 1; }
|
||||
|
||||
XTL::CMcpxVoiceClient::_settings XTL::CMcpxVoiceClient::default_settings =
|
||||
{
|
||||
0, // 0x08
|
||||
// ...
|
||||
};
|
|
@ -0,0 +1,227 @@
|
|||
// ******************************************************************
|
||||
// *
|
||||
// * This file is part of the Cxbx project.
|
||||
// *
|
||||
// * Cxbx and Cxbe are free software; you can redistribute them
|
||||
// * and/or modify them under the terms of the GNU General Public
|
||||
// * License as published by the Free Software Foundation; either
|
||||
// * version 2 of the license, or (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have recieved a copy of the GNU General Public License
|
||||
// * along with this program; see the file COPYING.
|
||||
// * If not, write to the Free Software Foundation, Inc.,
|
||||
// * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// *
|
||||
// * (c) 2020 RadWolfie
|
||||
// *
|
||||
// * All rights reserved
|
||||
// *
|
||||
// ******************************************************************
|
||||
#pragma once
|
||||
|
||||
#include "Cxbx.h"
|
||||
#include "core\hle\DSOUND\XbDSoundTypes.h"
|
||||
|
||||
namespace XTL {
|
||||
|
||||
// TODO: Everything, only small portions had been implemented.
|
||||
|
||||
struct audio_format {
|
||||
uint32_t audio_codec;
|
||||
uint32_t nChannels;
|
||||
uint32_t cbSize;
|
||||
int32_t nSamplesPerSec;
|
||||
uint32_t bitsPerSample;
|
||||
};
|
||||
|
||||
struct CUnknownGenericManager {
|
||||
// construct vtable (or grab ptr to existing)
|
||||
CUnknownGenericManager() : ref_count(1) {}
|
||||
|
||||
// all virtual functions are stored in local offset 0x00's pointer
|
||||
virtual ~CUnknownGenericManager() {}; // 0x00
|
||||
virtual uint32_t WINAPI AddRef() { return ++ref_count; }; // 0x04
|
||||
virtual uint32_t WINAPI Release() { return --ref_count; }; // 0x08
|
||||
|
||||
uint32_t ref_count; // 0x04
|
||||
};
|
||||
static_assert(sizeof(CUnknownGenericManager) == 0x08);
|
||||
|
||||
struct CUnknownTemplate {
|
||||
// construct vtable (or grab ptr to existing)
|
||||
CUnknownTemplate();
|
||||
|
||||
virtual ~CUnknownTemplate() {}; // 0x00
|
||||
virtual void WINAPI pUnknown_04() { throw std::exception("pUnknown_04"); }; // 0x04
|
||||
virtual void WINAPI pUnknown_08() { throw std::exception("pUnknown_08"); }; // 0x08
|
||||
virtual void WINAPI pUnknown_0C() { throw std::exception("pUnknown_0C"); }; // 0x0C
|
||||
virtual void WINAPI pUnknown_10() { throw std::exception("pUnknown_10"); }; // 0x10
|
||||
virtual void WINAPI pUnknown_14() { throw std::exception("pUnknown_14"); }; // 0x14
|
||||
virtual void WINAPI pUnknown_18() { throw std::exception("pUnknown_18"); }; // 0x18
|
||||
virtual void WINAPI pUnknown_1C() { throw std::exception("pUnknown_1C"); }; // 0x1C
|
||||
// If need to add more virtual functions, add them above here.
|
||||
uint32_t ref_count; // 0x04
|
||||
};
|
||||
static_assert(sizeof(CUnknownTemplate) == 0x08);
|
||||
|
||||
struct CMcpxVoiceClient: CUnknownTemplate {
|
||||
CMcpxVoiceClient() : settings(default_settings) {};
|
||||
// all virtual functions are stored in local offset 0x00's pointer
|
||||
virtual ~CMcpxVoiceClient() {};
|
||||
|
||||
// CUnknownTemplate // 0x00 - ???
|
||||
struct _settings
|
||||
{
|
||||
uint32_t Unknown2[(0x300-8)/4]; // 0x08 - ???
|
||||
}
|
||||
settings;
|
||||
|
||||
// global _settings for this class
|
||||
static _settings default_settings;
|
||||
};
|
||||
static_assert(sizeof(CMcpxVoiceClient) == 0x300);
|
||||
|
||||
struct CDirectSoundVoice : CUnknownGenericManager {
|
||||
CDirectSoundVoice(bool is3D);
|
||||
// all virtual functions are stored in local offset 0x00's pointer
|
||||
virtual ~CDirectSoundVoice();
|
||||
|
||||
// CUnknownGenericManager // 0x00 - ???
|
||||
union _u {
|
||||
struct _settings_interface
|
||||
{
|
||||
uint32_t unknown_08[0x300 / 4]; // 0x000 - 0x300 (unknown size, likely over 0x200 size.
|
||||
} settings_interface;
|
||||
|
||||
struct _settings_4034_lower {
|
||||
xbaddr p_unknown_08; // 0x008
|
||||
uint16_t unknown_0C; // 0x00C // zero'd - unknown
|
||||
XBOXADPCMWAVEFORMAT* p_audio_format; // 0x010 // Same as XBOXADPCMWAVEFORMAT / WAVEFORMATEX structure
|
||||
uint32_t pitch; // 0x014 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls.
|
||||
uint32_t volume; // 0x018 // default: (set volume - headroom)
|
||||
uint32_t headroom; // 0x01C // default: (set headroom then update volume)
|
||||
} settings_4034_lower;
|
||||
|
||||
struct _settings_4039_only {
|
||||
uint32_t unknown_08; // 0x008
|
||||
uint32_t audio_codec; // 0x00C // Setter is 32 bit, yet getter is 16 bit integer reader
|
||||
uint32_t nChannels; // 0x010
|
||||
uint32_t cbSize; // 0x014
|
||||
int32_t nSamplesPerSec_default; // 0x018 // Always original frequency for check if SetFrequency is given with 0 then use original one.
|
||||
uint32_t bitsPerSample; // 0x01C
|
||||
uint32_t pitch; // 0x020 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls.
|
||||
uint32_t volume; // 0x024 // (set volume - headroom)
|
||||
uint32_t headroom; // 0x028 // (set headroom then update volume)
|
||||
uint32_t unknown_2C[(0x300 - 0x2C) / 4]; // 0x02C - 0x300 (unknown size, likely over 0x200 size.
|
||||
} settings_4039_only;
|
||||
|
||||
struct _settings_4134_upper {
|
||||
uint32_t unknown_08; // 0x008
|
||||
uint16_t audio_codec; // 0x00C
|
||||
uint8_t nChannels; // 0x00E
|
||||
uint8_t cbSize; // 0x00F
|
||||
uint32_t nSamplesPerSec_default; // 0x010 // Always original frequency for check if SetFrequency is given with 0 then use original one.
|
||||
uint32_t bitsPerSample; // 0x014
|
||||
int32_t pitch; // 0x018 // Always init and custom pitch from SetFrequency, SetPitch, SetFormat, etc calls.
|
||||
uint32_t volume; // 0x01C // (set volume - headroom)
|
||||
uint32_t headroom; // 0x020 // (set headroom then update volume)
|
||||
uint32_t unknown_24[(0x300 - 0x24) / 4]; // 0x024 - 0x300 (unknown size, likely over 0x200 size.
|
||||
} settings_4134_upper;
|
||||
} u;
|
||||
static_assert(sizeof(_u) == 0x300);
|
||||
|
||||
struct {
|
||||
void (*GetFormat)(_u& u, audio_format& format);
|
||||
void (*SetFormat)(_u& u, audio_format format);
|
||||
uint32_t (*GetFrequencyDefault)(_u& u);
|
||||
int32_t (*GetPitch)(_u& u);
|
||||
void (*SetPitch)(_u& u, int32_t pitch);
|
||||
uint32_t (*GetVolume)(_u& u);
|
||||
void (*SetVolume)(_u& u, uint32_t volume);
|
||||
uint32_t (*GetHeadroom)(_u& u);
|
||||
void (*SetHeadroom)(_u& u, uint32_t headroom);
|
||||
} funcs;
|
||||
static_assert(sizeof(funcs) == 0x24);
|
||||
|
||||
static inline void GetFormat(CDirectSoundVoice* pThis, audio_format& format) {
|
||||
pThis->funcs.GetFormat(pThis->u, format);
|
||||
};
|
||||
static inline void SetFormat(CDirectSoundVoice* pThis, audio_format format) {
|
||||
pThis->funcs.SetFormat(pThis->u, format);
|
||||
};
|
||||
static inline uint32_t GetFrequencyDefault(CDirectSoundVoice* pThis) {
|
||||
return pThis->funcs.GetFrequencyDefault(pThis->u);
|
||||
};
|
||||
static inline int32_t GetPitch(CDirectSoundVoice* pThis) {
|
||||
return pThis->funcs.GetPitch(pThis->u);
|
||||
};
|
||||
static inline void SetPitch(CDirectSoundVoice* pThis, int32_t pitch) {
|
||||
pThis->funcs.SetPitch(pThis->u, pitch);
|
||||
};
|
||||
static inline uint32_t GetVolume(CDirectSoundVoice* pThis) {
|
||||
return pThis->funcs.GetVolume(pThis->u);
|
||||
};
|
||||
static inline void SetVolume(CDirectSoundVoice* pThis, uint32_t volume) {
|
||||
pThis->funcs.SetVolume(pThis->u, volume);
|
||||
};
|
||||
static inline uint32_t GetHeadroom(CDirectSoundVoice* pThis) {
|
||||
return pThis->funcs.GetHeadroom(pThis->u);
|
||||
};
|
||||
static inline void SetHeadroom(CDirectSoundVoice* pThis, uint32_t headroom) {
|
||||
pThis->funcs.SetHeadroom(pThis->u, headroom);
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(CDirectSoundVoice) == sizeof(CUnknownGenericManager) + sizeof(CDirectSoundVoice::_u) + sizeof(CDirectSoundVoice::funcs));
|
||||
|
||||
struct DSBUFFER_S : CUnknownTemplate {
|
||||
|
||||
// CUnknownTemplate unknown_00; // Offset 0x00 // -0x1C
|
||||
struct DSBUFFER_C {
|
||||
uint32_t unknown_08; // Offset 0x08 // -0x14
|
||||
CMcpxVoiceClient* p_CMcpxVoiceClient; // Offset 0x0C // -0x10
|
||||
CDirectSoundVoice* p_CDSVoice; // Offset 0x10 // -0x0C
|
||||
xbaddr p_unknown_14; // Offset 0x14 // -0x08 // (points to this address)
|
||||
xbaddr p_unknown_18; // Offset 0x18 // -0x04 // (points to above address)
|
||||
} dsb_c;
|
||||
static_assert(sizeof(DSBUFFER_C) == 0x14);
|
||||
|
||||
struct DSBUFFER_I {
|
||||
CDirectSoundVoice* p_CDSVoice; // Offset 0x1C // 0x00 // Same as p_CDSVoice (above); pThis
|
||||
CMcpxVoiceClient* p_CMcpxVoiceClient; // Offset 0x20 // 0x04 // Same as p_CMcpxVoiceClient (above)
|
||||
xbaddr p_unknown_24; // Offset 0x24 // 0x08
|
||||
xbaddr p_unknown_28; // Offset 0x28 // 0x0C
|
||||
uint32_t unknown_2C; // Offset 0x2C // 0x10 // was integer, later shift to offset 0x30
|
||||
uint32_t unknown_30; // Offset 0x30 // 0x14 // later shifted from offset 0x2C; integer
|
||||
} dsb_i;
|
||||
static_assert(sizeof(DSBUFFER_I) == 0x18);
|
||||
|
||||
DSBUFFER_S(bool is3D) {
|
||||
init(is3D);
|
||||
}
|
||||
virtual ~DSBUFFER_S() {
|
||||
delete dsb_c.p_CMcpxVoiceClient;
|
||||
delete dsb_c.p_CDSVoice;
|
||||
}
|
||||
virtual void init_member() {
|
||||
dsb_c.unknown_08 = 0;
|
||||
dsb_i.p_unknown_24 = xbnull;
|
||||
dsb_i.p_unknown_28 = xbnull;
|
||||
dsb_i.unknown_2C = xbnull;
|
||||
dsb_i.unknown_30 = xbnull;
|
||||
}
|
||||
virtual void init(bool is3D) {
|
||||
init_member();
|
||||
dsb_c.p_CMcpxVoiceClient = new CMcpxVoiceClient(); dsb_i.p_CMcpxVoiceClient = dsb_c.p_CMcpxVoiceClient;
|
||||
dsb_c.p_CDSVoice = new CDirectSoundVoice(is3D); dsb_i.p_CDSVoice = dsb_c.p_CDSVoice;
|
||||
dsb_c.p_unknown_18 = reinterpret_cast<xbaddr>(&dsb_c.p_unknown_14);
|
||||
dsb_c.p_unknown_14 = dsb_c.p_unknown_18;
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(DSBUFFER_S) == 0x34);
|
||||
|
||||
}
|
Loading…
Reference in New Issue