Rebase Code and State Segments in EffectMaps. fix PGR2
This commit is contained in:
parent
a04a079f19
commit
d49762d27e
|
@ -514,9 +514,9 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_SetEffectData)
|
|||
}
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: IDirectSound_DownloadEffectsImage
|
||||
// * patch: CDirectSound_DownloadEffectsImage
|
||||
// ******************************************************************
|
||||
xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage)
|
||||
xbox::hresult_xt WINAPI xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)
|
||||
(
|
||||
LPDIRECTSOUND8 pThis,
|
||||
LPCVOID pvImageBuffer,
|
||||
|
@ -536,22 +536,68 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(IDirectSound_DownloadEffectsImage)
|
|||
|
||||
// This function is relative to DSP for Interactive 3-D Audio Level 2 (I3DL2)
|
||||
|
||||
LOG_NOT_SUPPORTED();
|
||||
LOG_INCOMPLETE();
|
||||
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.
|
||||
|
||||
// Image buffer must be copied to internal and backed up 1st. the data might be referenced by the guest code later.
|
||||
// The Code Segment Address and State address in DSEFFECTMAP aEffectMaps[1] must be rebased to the internal buffer.
|
||||
|
||||
|
||||
// NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented.
|
||||
static PBYTE ImageBufferBackup = zeroptr; //The image buffer must be backed up since some game might reference ths data. ex. PGR2.
|
||||
if (ImageBufferBackup != zeroptr) {
|
||||
ExFreePool(ImageBufferBackup);
|
||||
}
|
||||
|
||||
ImageBufferBackup = static_cast<PBYTE>(ExAllocatePool(dwImageSize));
|
||||
if (ImageBufferBackup == zeroptr) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
std::memcpy(ImageBufferBackup, pvImageBuffer, dwImageSize); //Copy the ImageBuffer to internal backup Buffer.
|
||||
|
||||
//from here, all process should base on internal image buffer.
|
||||
|
||||
dword_xt N1 = *(PDWORD)(ImageBufferBackup + 0x804); //Total code segment size in dwords
|
||||
dword_xt N2 = *(PDWORD)(ImageBufferBackup + 0x80C); //Total state segment size in dwords
|
||||
PBYTE pImageDesc = ImageBufferBackup + 0x818 + 4 * (N1 + N2); //calculate the starting address of ImageDesc in image buffer
|
||||
DWORD EffectCount = ((LPDSEFFECTIMAGEDESC)pImageDesc)->dwEffectCount; //the first DWORD in ImageDesc is EffectCount.
|
||||
dword_xt ImageDescSize = 8 + 32 * EffectCount; //The size of ImageDesc is two Dwords (8 bytes) + 8 DWORS (32 bytes) for each effects.
|
||||
|
||||
//Process the DSEFFECTMAP in internal image buffer, rebase code segmemt address and state segment address of each effect.
|
||||
PBYTE pEffectMaps = (pImageDesc + 8); //EffectMaps array start from here.
|
||||
for (int effect_loop = 0; effect_loop < EffectCount; effect_loop++)
|
||||
{
|
||||
|
||||
PBYTE pCodeSeg = pEffectMaps + effect_loop * 32;
|
||||
*(PDWORD)pCodeSeg += (DWORD)ImageBufferBackup;
|
||||
|
||||
PBYTE pStateSeg = pEffectMaps + effect_loop * 32+8;
|
||||
*(PDWORD)pStateSeg += (DWORD)ImageBufferBackup;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// NOTE: this buffer should also be freed in IDirectSound_Release when the ref counter drops to zero, but that function is currently not implemented.
|
||||
static PBYTE ImageDescBuffer = zeroptr;
|
||||
if (ImageDescBuffer != zeroptr) {
|
||||
ExFreePool(ImageDescBuffer);
|
||||
}
|
||||
|
||||
ImageDescBuffer = static_cast<PBYTE>(ExAllocatePool(ImageDescSize));
|
||||
if (ImageDescBuffer == zeroptr) {
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
// NOTE: this is very wrong. The dsp image is encrypted, and thus simply copying the original encrypted image won't do any good.
|
||||
*ppImageDesc = ImageDescBuffer;
|
||||
std::memcpy(*ppImageDesc, pImageDesc, ImageDescSize);
|
||||
|
||||
// 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.
|
||||
|
|
|
@ -127,6 +127,50 @@ struct SharedDSBuffer : DSBUFFER_S {
|
|||
}
|
||||
};
|
||||
|
||||
typedef struct _DSEFFECTMAP {
|
||||
LPVOID lpvCodeSegment;
|
||||
DWORD dwCodeSize;
|
||||
LPVOID lpvStateSegment;
|
||||
DWORD dwStateSize;
|
||||
LPVOID lpvYMemorySegment;
|
||||
DWORD dwYMemorySize;
|
||||
LPVOID lpvScratchSegment;
|
||||
DWORD dwScratchSize;
|
||||
} DSEFFECTMAP, *LPDSEFFECTMAP;
|
||||
/*Members
|
||||
lpvCodeSegment
|
||||
Starting address of the DSP code segment for this effect.
|
||||
dwCodeSize
|
||||
Value that contains the code segment size, in DWORDs.
|
||||
lpvStateSegment
|
||||
Starting address of the effect state segment.
|
||||
dwStateSize
|
||||
Value that contains the size of the effect state segment, in DWORDs.
|
||||
lpvYMemorySegment
|
||||
Starting address of the DSP Y-memory segment.
|
||||
dwYMemorySize
|
||||
Value that contains the Y-memory segment size, in DWORDs.
|
||||
lpvScratchSegment
|
||||
Starting address of the scratch memory segment.
|
||||
dwScratchSize
|
||||
Value that contains the size of the scratch segment, in DWORDs.
|
||||
*/
|
||||
|
||||
typedef struct _DSEFFECTIMAGEDESC {
|
||||
DWORD dwEffectCount;
|
||||
DWORD dwTotalScratchSize;
|
||||
DSEFFECTMAP aEffectMaps[1];
|
||||
} DSEFFECTIMAGEDESC, *LPDSEFFECTIMAGEDESC;
|
||||
|
||||
/*Members
|
||||
dwEffectCount
|
||||
Value that contains the number of effects in the image.
|
||||
dwTotalScratchSize
|
||||
Value that contains the total amount of space required by effects that use scratch space for delay lines.
|
||||
aEffectMaps
|
||||
Variable-length array that contains the effect descriptions.
|
||||
*/
|
||||
|
||||
//Custom flags (4 bytes support up to 31 shifts,starting from 0)
|
||||
#define DSE_FLAG_PCM (1 << 0)
|
||||
#define DSE_FLAG_XADPCM (1 << 1)
|
||||
|
@ -414,9 +458,9 @@ xbox::hresult_xt WINAPI EMUPATCH(IDirectSound_SynchPlayback)
|
|||
);
|
||||
|
||||
// ******************************************************************
|
||||
// * patch: IDirectSound_DownloadEffectsImage
|
||||
// * patch: CDirectSound_DownloadEffectsImage
|
||||
// ******************************************************************
|
||||
xbox::hresult_xt WINAPI EMUPATCH(IDirectSound_DownloadEffectsImage)
|
||||
xbox::hresult_xt WINAPI EMUPATCH(CDirectSound_DownloadEffectsImage)
|
||||
(
|
||||
LPDIRECTSOUND8 pThis,
|
||||
LPCVOID pvImageBuffer,
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
#include "DirectSoundInline.hpp"
|
||||
|
||||
#include <core\kernel\support\EmuFile.h>
|
||||
|
||||
// TODO: Tasks need to do for DirectSound HLE
|
||||
// * Need create patches
|
||||
// * Ac97CreateMediaObject (Need OOVPA)
|
||||
|
@ -115,9 +117,36 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
|
|||
LOG_FUNC_ARG(ppImageDesc)
|
||||
LOG_FUNC_END;
|
||||
|
||||
LOG_NOT_SUPPORTED();
|
||||
LOG_INCOMPLETE();
|
||||
LPDIRECTSOUND8 pThis_tmp= zeroptr;
|
||||
PBYTE pvImageBuffer;
|
||||
dword_xt dwImageSize;
|
||||
|
||||
return S_OK;
|
||||
HANDLE hFile;
|
||||
DWORD dwBytesRead;
|
||||
LPSTR pszScratchFile;
|
||||
|
||||
//convert_pszImageName_to_pszScratchFile();
|
||||
std::string hostpath = CxbxConvertXboxToHostPath(std::string_view (pszImageName));
|
||||
|
||||
hFile = CreateFile(hostpath.c_str(),GENERIC_READ,0,NULL,OPEN_EXISTING,0,NULL);
|
||||
|
||||
dwImageSize = GetFileSize(hFile, NULL);
|
||||
|
||||
pvImageBuffer = new BYTE[dwImageSize];
|
||||
|
||||
BOOL bResult = ReadFile(hFile,pvImageBuffer,dwImageSize,&dwBytesRead,0);
|
||||
|
||||
xbox::hresult_xt result = xbox::EMUPATCH(CDirectSound_DownloadEffectsImage)(pThis_tmp, pvImageBuffer,dwImageSize,pImageLoc,ppImageDesc);
|
||||
|
||||
delete[] pvImageBuffer;
|
||||
|
||||
if (hFile != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
return result;// result;
|
||||
}
|
||||
|
||||
// ******************************************************************
|
||||
|
|
|
@ -312,7 +312,8 @@ std::map<const std::string, const xbox_patch_t> g_PatchTable = {
|
|||
PATCH_ENTRY("IDirectSound_CommitEffectData", xbox::EMUPATCH(IDirectSound_CommitEffectData), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("IDirectSound_CreateSoundBuffer", xbox::EMUPATCH(IDirectSound_CreateSoundBuffer), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("IDirectSound_CreateSoundStream", xbox::EMUPATCH(IDirectSound_CreateSoundStream), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("IDirectSound_DownloadEffectsImage", xbox::EMUPATCH(IDirectSound_DownloadEffectsImage), PATCH_HLE_DSOUND),
|
||||
// PATCH_ENTRY("IDirectSound_DownloadEffectsImage", xbox::EMUPATCH(IDirectSound_DownloadEffectsImage), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("CDirectSound_DownloadEffectsImage", xbox::EMUPATCH(CDirectSound_DownloadEffectsImage), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("IDirectSound_EnableHeadphones", xbox::EMUPATCH(IDirectSound_EnableHeadphones), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("IDirectSound_GetCaps", xbox::EMUPATCH(IDirectSound_GetCaps), PATCH_HLE_DSOUND),
|
||||
PATCH_ENTRY("IDirectSound_GetEffectData", xbox::EMUPATCH(IDirectSound_GetEffectData), PATCH_HLE_DSOUND),
|
||||
|
|
Loading…
Reference in New Issue