diff --git a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp index 59dc389a5..5ecaa7fc6 100644 --- a/src/core/hle/DSOUND/DirectSound/DirectSound.cpp +++ b/src/core/hle/DSOUND/DirectSound/DirectSound.cpp @@ -518,13 +518,13 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_SetEffectData) // ****************************************************************** xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage) ( - LPDIRECTSOUND8 pThis, - LPCVOID pvImageBuffer, - dword_xt dwImageSize, - PVOID pImageLoc, // TODO: Use this param - PVOID* ppImageDesc) // TODO: Use this param + LPDIRECTSOUND8 pThis, + LPCVOID pvImageBuffer, + dword_xt dwImageSize, + PVOID pImageLoc, // TODO: Use this param + PVOID* ppImageDesc) // TODO: Use this param { - DSoundMutexGuardLock; + DSoundMutexGuardLock; LOG_FUNC_BEGIN LOG_FUNC_ARG(pThis) @@ -534,11 +534,29 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage) LOG_FUNC_ARG(ppImageDesc) LOG_FUNC_END; - // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) + // This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2) - LOG_NOT_SUPPORTED(); - - return S_OK; + LOG_NOT_SUPPORTED(); + if(ppImageDesc)//If the guest code request a pointer to ImageDesc structure to be returned, then we should allocate a memory and create ImageDesc. + { + // Code block below is reversed from Otogi. + // ImageBuffer header starts from offset ox800 and ends in offset 0x817. actual DSP code segment starts from offset 0x818. + // DWORD at offset 0x804 and offset 0x80C should be the code segment sizes in dwords. + // ImageDesc is appended after code segments. There are additional two DWORDs data for each effect appended after ImageDesc which I have no idea what they are for. + DWORD N1 = *(DWORD *)((BYTE *)pvImageBuffer + 0x804); //first code segment size in dwords + DWORD N2 = *(DWORD *)((BYTE *)pvImageBuffer + 0x80C); //2nd code segment size in dwords + BYTE * pImageDesc = ((BYTE *)pvImageBuffer + 0x818 + 4 * (N1 + N2)); //calculate the starting address of ImageDesc inside the imagebuffer + DWORD EffectCount = *(DWORD *)pImageDesc; //the first DWORD in ImageDesc is EffectCount. + DWORD ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects. + if (*ppImageDesc = malloc(ImageDescSize)) //allocate a new memory to keep the ImageDesc for guest code since the imagebuffer should be freed after the image were downloaded. + { + memcpy(*ppImageDesc, pImageDesc, ImageDescSize); //copy the ImageDesc from ImageBuffer. + } + // with the code above, we could easily retrieve the address and size of ImageDesc within the image buffer. + // then we can allocate a new memory, copy the imageDesc from the image buffer to the newly allocated memory, + // then assign the newly allocated memory to the ppImageDesc. that's all. + } + return S_OK; } // ******************************************************************