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,
|
LPDIRECTSOUND8 pThis,
|
||||||
LPCVOID pvImageBuffer,
|
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)
|
// 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.
|
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.
|
// 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.
|
// 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.
|
// 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.
|
// 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
|
// Image buffer must be copied to internal and backed up 1st. the data might be referenced by the guest code later.
|
||||||
BYTE * pImageDesc = ((BYTE *)pvImageBuffer + 0x818 + 4 * (N1 + N2)); //calculate the starting address of ImageDesc inside the imagebuffer
|
// The Code Segment Address and State address in DSEFFECTMAP aEffectMaps[1] must be rebased to the internal buffer.
|
||||||
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.
|
// 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.
|
||||||
memcpy(*ppImageDesc, pImageDesc, ImageDescSize); //copy the ImageDesc from ImageBuffer.
|
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.
|
// 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 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.
|
// 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)
|
//Custom flags (4 bytes support up to 31 shifts,starting from 0)
|
||||||
#define DSE_FLAG_PCM (1 << 0)
|
#define DSE_FLAG_PCM (1 << 0)
|
||||||
#define DSE_FLAG_XADPCM (1 << 1)
|
#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,
|
LPDIRECTSOUND8 pThis,
|
||||||
LPCVOID pvImageBuffer,
|
LPCVOID pvImageBuffer,
|
||||||
|
|
|
@ -38,6 +38,8 @@
|
||||||
|
|
||||||
#include "DirectSoundInline.hpp"
|
#include "DirectSoundInline.hpp"
|
||||||
|
|
||||||
|
#include <core\kernel\support\EmuFile.h>
|
||||||
|
|
||||||
// TODO: Tasks need to do for DirectSound HLE
|
// TODO: Tasks need to do for DirectSound HLE
|
||||||
// * Need create patches
|
// * Need create patches
|
||||||
// * Ac97CreateMediaObject (Need OOVPA)
|
// * Ac97CreateMediaObject (Need OOVPA)
|
||||||
|
@ -115,9 +117,36 @@ xbox::hresult_xt WINAPI xbox::EMUPATCH(XAudioDownloadEffectsImage)
|
||||||
LOG_FUNC_ARG(ppImageDesc)
|
LOG_FUNC_ARG(ppImageDesc)
|
||||||
LOG_FUNC_END;
|
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_CommitEffectData", xbox::EMUPATCH(IDirectSound_CommitEffectData), PATCH_HLE_DSOUND),
|
||||||
PATCH_ENTRY("IDirectSound_CreateSoundBuffer", xbox::EMUPATCH(IDirectSound_CreateSoundBuffer), 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_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_EnableHeadphones", xbox::EMUPATCH(IDirectSound_EnableHeadphones), PATCH_HLE_DSOUND),
|
||||||
PATCH_ENTRY("IDirectSound_GetCaps", xbox::EMUPATCH(IDirectSound_GetCaps), 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),
|
PATCH_ENTRY("IDirectSound_GetEffectData", xbox::EMUPATCH(IDirectSound_GetEffectData), PATCH_HLE_DSOUND),
|
||||||
|
|
Loading…
Reference in New Issue